diff --git a/app/jobs/migrations/batch_update_pays_values_job.rb b/app/jobs/migrations/batch_update_pays_values_job.rb index 6e9ca4de9..01add5af8 100644 --- a/app/jobs/migrations/batch_update_pays_values_job.rb +++ b/app/jobs/migrations/batch_update_pays_values_job.rb @@ -74,8 +74,8 @@ class Migrations::BatchUpdatePaysValuesJob < ApplicationJob def perform(ids) ids.each do |id| pays_champ = Champs::PaysChamp.find(id) - next if pays_champ.valid? + next if pays_champ.valid?(pays_champ.public? ? :champs_public_value : :champs_private_value) code = APIGeoService.country_code(pays_champ.value) value = if code.present? APIGeoService.country_name(code) diff --git a/app/models/champs/boolean_champ.rb b/app/models/champs/boolean_champ.rb index f474944d7..6aac3e9fd 100644 --- a/app/models/champs/boolean_champ.rb +++ b/app/models/champs/boolean_champ.rb @@ -5,7 +5,11 @@ class Champs::BooleanChamp < Champ before_validation :set_value_to_nil, if: -> { value.blank? } before_validation :set_value_to_false, unless: -> { ([nil, TRUE_VALUE, FALSE_VALUE]).include?(value) } - validates :value, inclusion: [TRUE_VALUE, FALSE_VALUE], allow_nil: true, allow_blank: false + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } + validates :value, inclusion: [TRUE_VALUE, FALSE_VALUE], + allow_nil: true, + allow_blank: false, + if: :validate_champ_value? def true? value == TRUE_VALUE diff --git a/app/models/champs/civilite_champ.rb b/app/models/champs/civilite_champ.rb index 00e1eb247..7b4d9df1c 100644 --- a/app/models/champs/civilite_champ.rb +++ b/app/models/champs/civilite_champ.rb @@ -1,5 +1,8 @@ class Champs::CiviliteChamp < Champ - validates :value, inclusion: ["M.", "Mme"], allow_nil: true, allow_blank: false + validates :value, inclusion: ["M.", "Mme"], + allow_nil: true, + allow_blank: false, + if: -> { validate_champ_value? || validation_context == :prefill } def legend_label? true diff --git a/app/models/champs/cnaf_champ.rb b/app/models/champs/cnaf_champ.rb index bf8013266..4166312d3 100644 --- a/app/models/champs/cnaf_champ.rb +++ b/app/models/champs/cnaf_champ.rb @@ -1,5 +1,6 @@ class Champs::CnafChamp < Champs::TextChamp # see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/cnaf-input-validation.middleware.ts + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validates :numero_allocataire, format: { with: /\A\d{1,7}\z/ }, if: -> { code_postal.present? && validate_champ_value? } validates :code_postal, format: { with: /\A\w{5}\z/ }, if: -> { numero_allocataire.present? && validate_champ_value? } diff --git a/app/models/champs/decimal_number_champ.rb b/app/models/champs/decimal_number_champ.rb index 3339555d9..f6fa77eec 100644 --- a/app/models/champs/decimal_number_champ.rb +++ b/app/models/champs/decimal_number_champ.rb @@ -14,7 +14,7 @@ class Champs::DecimalNumberChamp < Champ message: -> (object, _data) { "« #{object.libelle} » " + object.errors.generate_message(:value, :not_a_number) } - } + }, if: -> { validate_champ_value? || validation_context == :prefill } def for_export processed_value diff --git a/app/models/champs/departement_champ.rb b/app/models/champs/departement_champ.rb index c6f9dfa01..c353f1fc3 100644 --- a/app/models/champs/departement_champ.rb +++ b/app/models/champs/departement_champ.rb @@ -1,5 +1,6 @@ class Champs::DepartementChamp < Champs::TextChamp store_accessor :value_json, :code_region + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validate :value_in_departement_names, unless: -> { value.nil? } validate :external_id_in_departement_codes, unless: -> { external_id.nil? } before_save :store_code_region diff --git a/app/models/champs/dgfip_champ.rb b/app/models/champs/dgfip_champ.rb index e702f84aa..3ce86c8c0 100644 --- a/app/models/champs/dgfip_champ.rb +++ b/app/models/champs/dgfip_champ.rb @@ -1,5 +1,6 @@ class Champs::DgfipChamp < Champs::TextChamp # see https://github.com/betagouv/api-particulier/blob/master/src/presentation/middlewares/dgfip-input-validation.middleware.ts + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validates :numero_fiscal, format: { with: /\A\w{13,14}\z/ }, if: -> { reference_avis.present? && validate_champ_value? } validates :reference_avis, format: { with: /\A\w{13,14}\z/ }, if: -> { numero_fiscal.present? && validate_champ_value? } diff --git a/app/models/champs/dossier_link_champ.rb b/app/models/champs/dossier_link_champ.rb index ba73ddce6..bbced5dbe 100644 --- a/app/models/champs/dossier_link_champ.rb +++ b/app/models/champs/dossier_link_champ.rb @@ -1,4 +1,5 @@ class Champs::DossierLinkChamp < Champ + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validate :value_integerable, if: -> { value.present? }, on: :prefill private diff --git a/app/models/champs/drop_down_list_champ.rb b/app/models/champs/drop_down_list_champ.rb index 4d29c7741..5171a880e 100644 --- a/app/models/champs/drop_down_list_champ.rb +++ b/app/models/champs/drop_down_list_champ.rb @@ -5,6 +5,7 @@ class Champs::DropDownListChamp < Champ OTHER = '__other__' delegate :options_without_empty_value_when_mandatory, to: :type_de_champ + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validate :value_is_in_options, unless: -> { value.blank? || drop_down_other? } def render_as_radios? diff --git a/app/models/champs/email_champ.rb b/app/models/champs/email_champ.rb index 5dfcff902..de3618ab2 100644 --- a/app/models/champs/email_champ.rb +++ b/app/models/champs/email_champ.rb @@ -1,5 +1,6 @@ class Champs::EmailChamp < Champs::TextChamp include EmailSanitizableConcern before_validation -> { sanitize_email(:value) } + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validates :value, allow_blank: true, format: { with: StrictEmailValidator::REGEXP }, if: :validate_champ_value? end diff --git a/app/models/champs/engagement_juridique_champ.rb b/app/models/champs/engagement_juridique_champ.rb index 903365e8d..f3a148436 100644 --- a/app/models/champs/engagement_juridique_champ.rb +++ b/app/models/champs/engagement_juridique_champ.rb @@ -1,7 +1,8 @@ class Champs::EngagementJuridiqueChamp < Champ # cf: https://communaute.chorus-pro.gouv.fr/documentation/creer-un-engagement/#1522314752186-a34f3662-0644b5d1-16c22add-8ea097de-3a0a + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validates_with ExpressionReguliereValidator, expression_reguliere: /([A-Z]|[0-9]|\-|\_|\+|\/)+/, expression_reguliere_error_message: "Le numéro d'EJ ne peut contenir que des caractères alphanumérique et les caractères spéciaux suivant : “-“ ; “_“ ; “+“ ; “/“", - if: -> { validation_context != :brouillon } + if: :validate_champ_value? end diff --git a/app/models/champs/epci_champ.rb b/app/models/champs/epci_champ.rb index 1d1d06f88..8d61e762c 100644 --- a/app/models/champs/epci_champ.rb +++ b/app/models/champs/epci_champ.rb @@ -3,6 +3,7 @@ class Champs::EpciChamp < Champs::TextChamp before_validation :on_departement_change before_validation :on_epci_name_changes + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validate :code_departement_in_departement_codes, unless: -> { code_departement.nil? } validate :external_id_in_departement_epci_codes, unless: -> { code_departement.nil? || external_id.nil? } validate :value_in_departement_epci_names, unless: -> { code_departement.nil? || external_id.nil? || value.nil? } diff --git a/app/models/champs/expression_reguliere_champ.rb b/app/models/champs/expression_reguliere_champ.rb index d85a4f13f..b6d05dbd5 100644 --- a/app/models/champs/expression_reguliere_champ.rb +++ b/app/models/champs/expression_reguliere_champ.rb @@ -1,3 +1,4 @@ class Champs::ExpressionReguliereChamp < Champ + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validates_with ExpressionReguliereValidator, if: :validate_champ_value? end diff --git a/app/models/champs/iban_champ.rb b/app/models/champs/iban_champ.rb index 578820a75..2205e5fca 100644 --- a/app/models/champs/iban_champ.rb +++ b/app/models/champs/iban_champ.rb @@ -1,4 +1,5 @@ class Champs::IbanChamp < Champ + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validates_with IbanValidator, if: :validate_champ_value? after_validation :format_iban diff --git a/app/models/champs/integer_number_champ.rb b/app/models/champs/integer_number_champ.rb index deaf3b5f9..b913cf9c6 100644 --- a/app/models/champs/integer_number_champ.rb +++ b/app/models/champs/integer_number_champ.rb @@ -7,7 +7,7 @@ class Champs::IntegerNumberChamp < Champ # i18n-tasks-use t('errors.messages.not_an_integer') "« #{object.libelle} » " + object.errors.generate_message(:value, :not_an_integer) } - } + }, if: -> { validate_champ_value? || validation_context == :prefill } def for_export processed_value diff --git a/app/models/champs/multiple_drop_down_list_champ.rb b/app/models/champs/multiple_drop_down_list_champ.rb index 021040a31..1291512b5 100644 --- a/app/models/champs/multiple_drop_down_list_champ.rb +++ b/app/models/champs/multiple_drop_down_list_champ.rb @@ -1,4 +1,5 @@ class Champs::MultipleDropDownListChamp < Champ + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validate :values_are_in_options, if: -> { value.present? } def options? diff --git a/app/models/champs/pays_champ.rb b/app/models/champs/pays_champ.rb index 5029deea6..9318a5ed6 100644 --- a/app/models/champs/pays_champ.rb +++ b/app/models/champs/pays_champ.rb @@ -1,6 +1,15 @@ class Champs::PaysChamp < Champs::TextChamp - validates :value, inclusion: APIGeoService.countries.pluck(:name), allow_nil: true, allow_blank: false - validates :external_id, inclusion: APIGeoService.countries.pluck(:code), allow_nil: true, allow_blank: false + with_options if: :validate_champ_value? do + validates :external_id, inclusion: APIGeoService.countries.pluck(:code), allow_nil: true, allow_blank: false + validates :value, inclusion: APIGeoService.countries.pluck(:name), allow_nil: true, allow_blank: false + end + + # def value=(code) can reset champs to nil if value is empty, in case of prefill + # we do not want to try to save the champ with an nil value + with_options if: -> { validation_context == :prefill } do + validates :external_id, inclusion: APIGeoService.countries.pluck(:code), allow_nil: false, allow_blank: false + validates :value, inclusion: APIGeoService.countries.pluck(:name), allow_nil: false, allow_blank: false + end def for_export [name, code] @@ -26,8 +35,13 @@ class Champs::PaysChamp < Champs::TextChamp self.external_id = nil super(nil) elsif code != value - self.external_id = APIGeoService.country_code(code) - super(code) + self.external_id = APIGeoService.country_code(code) # lookup by code which is a country name + + if self.external_id # if we match a country code, lookup for country name with code + super(APIGeoService.country_name(self.external_id, locale: 'FR')) + else # if we did not match any country code, external_id is nil as well as value + super(nil) + end end end diff --git a/app/models/champs/phone_champ.rb b/app/models/champs/phone_champ.rb index 1d44152ad..5b85a83be 100644 --- a/app/models/champs/phone_champ.rb +++ b/app/models/champs/phone_champ.rb @@ -25,7 +25,8 @@ class Champs::PhoneChamp < Champs::TextChamp possible: true, allow_blank: true, message: I18n.t(:not_a_phone, scope: 'activerecord.errors.messages') - }, unless: -> { Phonelib.valid_for_countries?(value, DEFAULT_COUNTRY_CODES) } + }, + if: -> { (validate_champ_value? || validation_context == :prefill) && !Phonelib.valid_for_countries?(value, DEFAULT_COUNTRY_CODES) } def to_s return '' if value.blank? diff --git a/app/models/champs/piece_justificative_champ.rb b/app/models/champs/piece_justificative_champ.rb index 0ccbb83d7..f26e2ea06 100644 --- a/app/models/champs/piece_justificative_champ.rb +++ b/app/models/champs/piece_justificative_champ.rb @@ -1,6 +1,7 @@ class Champs::PieceJustificativeChamp < Champ FILE_MAX_SIZE = 200.megabytes + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validates :piece_justificative_file, size: { less_than: FILE_MAX_SIZE }, if: -> { !type_de_champ.skip_pj_validation } diff --git a/app/models/champs/region_champ.rb b/app/models/champs/region_champ.rb index 5e2c60b05..1765fdf1c 100644 --- a/app/models/champs/region_champ.rb +++ b/app/models/champs/region_champ.rb @@ -1,4 +1,5 @@ class Champs::RegionChamp < Champs::TextChamp + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validate :value_in_region_names, unless: -> { value.nil? } validate :external_id_in_region_codes, unless: -> { external_id.nil? } diff --git a/app/models/champs/rna_champ.rb b/app/models/champs/rna_champ.rb index e6bd55ec4..430526d8a 100644 --- a/app/models/champs/rna_champ.rb +++ b/app/models/champs/rna_champ.rb @@ -1,6 +1,7 @@ class Champs::RNAChamp < Champ include RNAChampAssociationFetchableConcern + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validates :value, allow_blank: true, format: { with: /\AW[0-9A-Z]{9}\z/, message: I18n.t(:not_a_rna, scope: 'activerecord.errors.messages') }, if: :validate_champ_value? diff --git a/app/models/champs/titre_identite_champ.rb b/app/models/champs/titre_identite_champ.rb index a24d7bef2..3778b295e 100644 --- a/app/models/champs/titre_identite_champ.rb +++ b/app/models/champs/titre_identite_champ.rb @@ -1,6 +1,7 @@ class Champs::TitreIdentiteChamp < Champ FILE_MAX_SIZE = 20.megabytes ACCEPTED_FORMATS = ['image/png', 'image/jpeg'] + # TODO: if: -> { validate_champ_value? || validation_context == :prefill } validates :piece_justificative_file, content_type: ACCEPTED_FORMATS, size: { less_than: FILE_MAX_SIZE } def main_value_name diff --git a/spec/controllers/instructeurs/dossiers_controller_spec.rb b/spec/controllers/instructeurs/dossiers_controller_spec.rb index 67316d102..1cd243e76 100644 --- a/spec/controllers/instructeurs/dossiers_controller_spec.rb +++ b/spec/controllers/instructeurs/dossiers_controller_spec.rb @@ -940,14 +940,18 @@ describe Instructeurs::DossiersController, type: :controller do describe "#update_annotations" do let(:procedure) do - create(:procedure, :published, types_de_champ_private: [ + create(:procedure, :published, types_de_champ_public:, types_de_champ_private:, instructeurs: instructeurs) + end + let(:types_de_champ_private) do + [ { type: :multiple_drop_down_list }, { type: :linked_drop_down_list }, { type: :datetime }, { type: :repetition, children: [{}] }, { type: :drop_down_list, options: [:a, :b, :other] } - ], instructeurs: instructeurs) + ] end + let(:types_de_champ_public) { [] } let(:dossier) { create(:dossier, :en_construction, :with_populated_annotations, procedure: procedure) } let(:another_instructeur) { create(:instructeur) } let(:now) { Time.zone.parse('01/01/2100') } @@ -958,24 +962,105 @@ describe Instructeurs::DossiersController, type: :controller do let(:champ_repetition) { dossier.champs_private.fourth } let(:champ_drop_down_list) { dossier.champs_private.fifth } - before do - expect(controller.current_instructeur).to receive(:mark_tab_as_seen).with(dossier, :annotations_privees) - another_instructeur.follow(dossier) - Timecop.freeze(now) - patch :update_annotations, params: params, format: :turbo_stream + context 'when no invalid champs_public' do + context "with new values for champs_private" do + before do + expect(controller.current_instructeur).to receive(:mark_tab_as_seen).with(dossier, :annotations_privees) + another_instructeur.follow(dossier) + Timecop.freeze(now) + patch :update_annotations, params: params, format: :turbo_stream - champ_multiple_drop_down_list.reload - champ_linked_drop_down_list.reload - champ_datetime.reload - champ_repetition.reload - champ_drop_down_list.reload + champ_multiple_drop_down_list.reload + champ_linked_drop_down_list.reload + champ_datetime.reload + champ_repetition.reload + champ_drop_down_list.reload + end + + after do + Timecop.return + end + let(:params) do + { + procedure_id: procedure.id, + dossier_id: dossier.id, + dossier: { + champs_private_attributes: { + '0': { + id: champ_multiple_drop_down_list.id, + value: ['', 'val1', 'val2'] + }, + '1': { + id: champ_datetime.id, + value: '2019-12-21T13:17' + }, + '2': { + id: champ_linked_drop_down_list.id, + primary_value: 'primary', + secondary_value: 'secondary' + }, + '3': { + id: champ_repetition.champs.first.id, + value: 'text' + }, + '4': { + id: champ_drop_down_list.id, + value: '__other__', + value_other: 'other value' + } + } + } + } + end + + it { + expect(champ_multiple_drop_down_list.value).to eq('["val1","val2"]') + expect(champ_linked_drop_down_list.primary_value).to eq('primary') + expect(champ_linked_drop_down_list.secondary_value).to eq('secondary') + expect(champ_datetime.value).to eq(Time.zone.parse('2019-12-21T13:17:00').iso8601) + expect(champ_repetition.champs.first.value).to eq('text') + expect(champ_drop_down_list.value).to eq('other value') + expect(dossier.reload.last_champ_private_updated_at).to eq(now) + expect(response).to have_http_status(200) + } + + it 'updates the annotations' do + Timecop.travel(now + 1.hour) + expect(instructeur.followed_dossiers.with_notifications).to eq([]) + expect(another_instructeur.followed_dossiers.with_notifications).to eq([dossier.reload]) + end + end + + context "without new values for champs_private" do + let(:params) do + { + procedure_id: procedure.id, + dossier_id: dossier.id, + dossier: { + champs_private_attributes: {}, + champs_public_attributes: { + '0': { + id: champ_multiple_drop_down_list.id, + value: ['', 'val1', 'val2'] + } + } + } + } + end + + it { + expect(dossier.reload.last_champ_private_updated_at).to eq(nil) + expect(response).to have_http_status(200) + } + end end - after do - Timecop.return - end - - context "with new values for champs_private" do + context 'with invalid champs_public (DecimalNumberChamp)' do + let(:types_de_champ_public) do + [ + { type: :decimal_number } + ] + end let(:params) do { procedure_id: procedure.id, @@ -983,72 +1068,22 @@ describe Instructeurs::DossiersController, type: :controller do dossier: { champs_private_attributes: { '0': { - id: champ_multiple_drop_down_list.id, - value: ['', 'val1', 'val2'] - }, - '1': { id: champ_datetime.id, - value: '2019-12-21T13:17' - }, - '2': { - id: champ_linked_drop_down_list.id, - primary_value: 'primary', - secondary_value: 'secondary' - }, - '3': { - id: champ_repetition.champs.first.id, - value: 'text' - }, - '4': { - id: champ_drop_down_list.id, - value: '__other__', - value_other: 'other value' + value: '2024-03-30T07:03' } } } } end - it { - expect(champ_multiple_drop_down_list.value).to eq('["val1","val2"]') - expect(champ_linked_drop_down_list.primary_value).to eq('primary') - expect(champ_linked_drop_down_list.secondary_value).to eq('secondary') - expect(champ_datetime.value).to eq(Time.zone.parse('2019-12-21T13:17:00').iso8601) - expect(champ_repetition.champs.first.value).to eq('text') - expect(champ_drop_down_list.value).to eq('other value') - expect(dossier.reload.last_champ_private_updated_at).to eq(now) - expect(response).to have_http_status(200) - } - - it 'updates the annotations' do - Timecop.travel(now + 1.hour) - expect(instructeur.followed_dossiers.with_notifications).to eq([]) - expect(another_instructeur.followed_dossiers.with_notifications).to eq([dossier.reload]) + it 'update champs_private' do + too_long_float = '3.1415' + dossier.champs_public.first.update_column(:value, too_long_float) + patch :update_annotations, params: params, format: :turbo_stream + champ_datetime.reload + expect(champ_datetime.value).to eq(Time.zone.parse('2024-03-30T07:03:00').iso8601) end end - - context "without new values for champs_private" do - let(:params) do - { - procedure_id: procedure.id, - dossier_id: dossier.id, - dossier: { - champs_private_attributes: {}, - champs_public_attributes: { - '0': { - id: champ_multiple_drop_down_list.id, - value: ['', 'val1', 'val2'] - } - } - } - } - end - - it { - expect(dossier.reload.last_champ_private_updated_at).to eq(nil) - expect(response).to have_http_status(200) - } - end end describe "#telecharger_pjs" do diff --git a/spec/jobs/migrations/batch_update_pays_values_job_spec.rb b/spec/jobs/migrations/batch_update_pays_values_job_spec.rb index 25531daa6..65670e49c 100644 --- a/spec/jobs/migrations/batch_update_pays_values_job_spec.rb +++ b/spec/jobs/migrations/batch_update_pays_values_job_spec.rb @@ -1,12 +1,8 @@ describe Migrations::BatchUpdatePaysValuesJob, type: :job do - before do - pays_champ.save(validate: false) - end - subject { described_class.perform_now([pays_champ.id]) } context "the value is correct" do - let(:pays_champ) { build(:champ_pays, value: 'France', external_id: 'FR') } + let(:pays_champ) { create(:champ_pays).tap { _1.update_columns(value: 'France', external_id: 'FR') } } it 'does not change it' do subject @@ -16,7 +12,7 @@ describe Migrations::BatchUpdatePaysValuesJob, type: :job do end context "the value is incorrect" do - let(:pays_champ) { build(:champ_pays, value: 'Incorrect') } + let(:pays_champ) { create(:champ_pays).tap { _1.update_columns(value: 'Incorrect') } } it 'updates value to nil' do subject @@ -26,7 +22,7 @@ describe Migrations::BatchUpdatePaysValuesJob, type: :job do end context "the value is easily cleanable" do - let(:pays_champ) { build(:champ_pays, value: 'Vietnam') } + let(:pays_champ) { create(:champ_pays).tap { _1.update_columns(value: 'Vietnam') } } it 'cleans the value' do subject @@ -36,7 +32,7 @@ describe Migrations::BatchUpdatePaysValuesJob, type: :job do end context "the value is hard to clean" do - let(:pays_champ) { build(:champ_pays, value: 'CHRISTMAS (ILE)') } + let(:pays_champ) { create(:champ_pays).tap { _1.update_columns(value: 'CHRISTMAS (ILE)') } } it 'cleans the value' do subject diff --git a/spec/models/champs/decimal_number_champ_spec.rb b/spec/models/champs/decimal_number_champ_spec.rb index 214353607..18dc76d4d 100644 --- a/spec/models/champs/decimal_number_champ_spec.rb +++ b/spec/models/champs/decimal_number_champ_spec.rb @@ -1,43 +1,54 @@ describe Champs::DecimalNumberChamp do - subject { build(:champ_decimal_number, value: value).tap(&:valid?) } + let(:champ) { build(:champ_decimal_number, value:) } + subject { champ.validate(:champs_public_value) } - describe '#valid?' do + describe 'validation' do context 'when the value is integer number' do let(:value) { 2 } - it { is_expected.to be_valid } + it { is_expected.to be_truthy } end context 'when the value is decimal number' do let(:value) { 2.6 } - it { is_expected.to be_valid } + it { is_expected.to be_truthy } end context 'when the value is not a number' do let(:value) { 'toto' } - it { is_expected.to_not be_valid } - it { expect(subject.errors[:value]).to eq(["« #{subject.libelle} » doit comprendre maximum 3 chiffres après la virgule", "« #{subject.libelle} » n'est pas un nombre"]) } + it 'is not valid and contains expected error' do + expect(subject).to be_falsey + expect(champ.errors[:value]).to eq(["« #{champ.libelle} » doit comprendre maximum 3 chiffres après la virgule", "« #{champ.libelle} » n'est pas un nombre"]) + end end context 'when the value has too many decimal' do let(:value) { '2.6666' } - it { is_expected.to_not be_valid } - it { expect(subject.errors[:value]).to eq(["« #{subject.libelle} » doit comprendre maximum 3 chiffres après la virgule"]) } + it 'is not valid and contains expected error' do + expect(subject).to be_falsey + expect(champ.errors[:value]).to eq(["« #{champ.libelle} » doit comprendre maximum 3 chiffres après la virgule"]) + end end context 'when the value is blank' do let(:value) { '' } - it { is_expected.to be_valid } + it { is_expected.to be_truthy } end context 'when the value is nil' do let(:value) { nil } - it { is_expected.to be_valid } + it { is_expected.to be_truthy } + end + + context 'when the champ is private, value is invalid, but validation is public' do + let(:champ) { build(:champ_decimal_number, :private, value:) } + let(:value) { '2.6666' } + it { is_expected.to be_truthy } end end end diff --git a/spec/models/champs/integer_number_champ_spec.rb b/spec/models/champs/integer_number_champ_spec.rb index d7cb82569..3eaf9bc8c 100644 --- a/spec/models/champs/integer_number_champ_spec.rb +++ b/spec/models/champs/integer_number_champ_spec.rb @@ -1,37 +1,42 @@ describe Champs::IntegerNumberChamp do - subject { build(:champ_integer_number, value: value).tap(&:valid?) } + let(:champ) { build(:champ_integer_number, value:) } + subject { champ.validate(:champs_public_value) } describe '#valid?' do context 'when the value is integer number' do let(:value) { 2 } - it { is_expected.to be_valid } + it { is_expected.to be_truthy } end context 'when the value is decimal number' do let(:value) { 2.6 } - it { is_expected.to_not be_valid } - it { expect(subject.errors[:value]).to eq(["« #{subject.libelle} » doit être un nombre entier (sans chiffres après la virgule)"]) } + it 'is not valid and contains errors' do + is_expected.to be_falsey + expect(champ.errors[:value]).to eq(["« #{champ.libelle} » doit être un nombre entier (sans chiffres après la virgule)"]) + end end context 'when the value is not a number' do let(:value) { 'toto' } - it { is_expected.to_not be_valid } - it { expect(subject.errors[:value]).to eq(["« #{subject.libelle} » doit être un nombre entier (sans chiffres après la virgule)"]) } + it 'is not valid and contains errors' do + is_expected.to be_falsey + expect(champ.errors[:value]).to eq(["« #{champ.libelle} » doit être un nombre entier (sans chiffres après la virgule)"]) + end end context 'when the value is blank' do let(:value) { '' } - it { is_expected.to be_valid } + it { is_expected.to be_truthy } end context 'when the value is nil' do let(:value) { nil } - it { is_expected.to be_valid } + it { is_expected.to be_truthy } end end end diff --git a/spec/models/champs/phone_champ_spec.rb b/spec/models/champs/phone_champ_spec.rb index 275986c33..e8e18e752 100644 --- a/spec/models/champs/phone_champ_spec.rb +++ b/spec/models/champs/phone_champ_spec.rb @@ -1,44 +1,45 @@ describe Champs::PhoneChamp do - let(:phone_champ) { build(:champ_phone) } + let(:champ) { build(:champ_phone) } + # subject { champ } - describe '#valid?' do + describe '#validate' do it do - expect(champ_with_value(nil)).to be_valid - expect(champ_with_value("0123456789 0123456789")).to_not be_valid - expect(champ_with_value("01.23.45.67.89 01.23.45.67.89")).to_not be_valid - expect(champ_with_value("3646")).to be_valid - expect(champ_with_value("0123456789")).to be_valid - expect(champ_with_value("01.23.45.67.89")).to be_valid - expect(champ_with_value("0123 45.67.89")).to be_valid - expect(champ_with_value("0033 123-456-789")).to be_valid - expect(champ_with_value("0033 123-456-789")).to be_valid - expect(champ_with_value("0033(0)123456789")).to be_valid - expect(champ_with_value("+33-1.23.45.67.89")).to be_valid - expect(champ_with_value("+33 - 123 456 789")).to be_valid - expect(champ_with_value("+33(0) 123 456 789")).to be_valid - expect(champ_with_value("+33 (0)123 45 67 89")).to be_valid - expect(champ_with_value("+33 (0)1 2345-6789")).to be_valid - expect(champ_with_value("+33(0) - 123456789")).to be_valid - expect(champ_with_value("+1(0) - 123456789")).to be_valid - expect(champ_with_value("+49 2109 87654321")).to be_valid - expect(champ_with_value("012345678")).to be_valid + expect(champ_with_value(nil).validate(:champs_public_value)).to be_truthy + expect(champ_with_value("0123456789 0123456789").validate(:champs_public_value)).to_not be_truthy + expect(champ_with_value("01.23.45.67.89 01.23.45.67.89").validate(:champs_public_value)).to_not be_truthy + expect(champ_with_value("3646").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("0123456789").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("01.23.45.67.89").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("0123 45.67.89").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("0033 123-456-789").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("0033 123-456-789").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("0033(0)123456789").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("+33-1.23.45.67.89").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("+33 - 123 456 789").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("+33(0) 123 456 789").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("+33 (0)123 45 67 89").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("+33 (0)1 2345-6789").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("+33(0) - 123456789").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("+1(0) - 123456789").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("+49 2109 87654321").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("012345678").validate(:champs_public_value)).to be_truthy # DROM numbers should be valid - expect(champ_with_value("06 96 04 78 07")).to be_valid - expect(champ_with_value("05 94 22 31 31")).to be_valid - expect(champ_with_value("+594 5 94 22 31 31")).to be_valid + expect(champ_with_value("06 96 04 78 07").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("05 94 22 31 31").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("+594 5 94 22 31 31").validate(:champs_public_value)).to be_truthy # polynesian numbers should not return errors in any way ## landline numbers start with 40 or 45 - expect(champ_with_value("45187272")).to be_valid - expect(champ_with_value("40 473 500")).to be_valid - expect(champ_with_value("40473500")).to be_valid - expect(champ_with_value("45473500")).to be_valid + expect(champ_with_value("45187272").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("40 473 500").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("40473500").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("45473500").validate(:champs_public_value)).to be_truthy ## +689 is the international indicator - expect(champ_with_value("+689 45473500")).to be_valid - expect(champ_with_value("0145473500")).to be_valid + expect(champ_with_value("+689 45473500").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("0145473500").validate(:champs_public_value)).to be_truthy ## polynesian mobile numbers start with 87, 88, 89 - expect(champ_with_value("87473500")).to be_valid - expect(champ_with_value("88473500")).to be_valid - expect(champ_with_value("89473500")).to be_valid + expect(champ_with_value("87473500").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("88473500").validate(:champs_public_value)).to be_truthy + expect(champ_with_value("89473500").validate(:champs_public_value)).to be_truthy end end @@ -61,6 +62,6 @@ describe Champs::PhoneChamp do end def champ_with_value(number) - phone_champ.tap { |c| c.value = number } + champ.tap { |c| c.value = number } end end diff --git a/spec/models/engagement_juridique_champ_spec.rb b/spec/models/engagement_juridique_champ_spec.rb index 7d5306fae..f704fa237 100644 --- a/spec/models/engagement_juridique_champ_spec.rb +++ b/spec/models/engagement_juridique_champ_spec.rb @@ -1,7 +1,7 @@ describe Champs::EngagementJuridiqueChamp do describe 'validation' do let(:champ) { build(:champ_engagement_juridique, value: value) } - subject { champ.valid? } + subject { champ.validate(:champs_public_value) } context 'with [A-Z]' do let(:value) { "ABC" }