From d5ffd61ab65b3be8deb98dc39de5ca3bf36b421c Mon Sep 17 00:00:00 2001 From: sebastiencarceles Date: Tue, 24 Jan 2023 15:10:25 +0100 Subject: [PATCH] validate values inclusion --- .../champs/multiple_drop_down_list_champ.rb | 9 +++++ app/models/prefill_params.rb | 1 + config/locales/en.yml | 4 ++ config/locales/fr.yml | 4 ++ .../instructeurs/dossiers_controller_spec.rb | 6 +-- spec/factories/champ.rb | 2 +- spec/models/champ_spec.rb | 6 +-- .../multiple_drop_down_list_champ_spec.rb | 38 +++++++++++++++++++ spec/models/prefill_params_spec.rb | 1 + 9 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 spec/models/champs/multiple_drop_down_list_champ_spec.rb diff --git a/app/models/champs/multiple_drop_down_list_champ.rb b/app/models/champs/multiple_drop_down_list_champ.rb index 365332e30..29ce06dcf 100644 --- a/app/models/champs/multiple_drop_down_list_champ.rb +++ b/app/models/champs/multiple_drop_down_list_champ.rb @@ -23,6 +23,8 @@ class Champs::MultipleDropDownListChamp < Champ before_save :format_before_save + validate :values_are_in_options, if: -> { value.present? } + def options? drop_down_list_options? end @@ -90,4 +92,11 @@ class Champs::MultipleDropDownListChamp < Champ end end end + + def values_are_in_options + return if (json = JSON.parse(value) - ['']).empty? + return if json.filter { |val| enabled_non_empty_options.exclude?(val) }.empty? + + errors.add(:value, :not_in_options) + end end diff --git a/app/models/prefill_params.rb b/app/models/prefill_params.rb index f0841039a..4af3e8532 100644 --- a/app/models/prefill_params.rb +++ b/app/models/prefill_params.rb @@ -42,6 +42,7 @@ class PrefillParams TypeDeChamp.type_champs.fetch(:pays), TypeDeChamp.type_champs.fetch(:regions), TypeDeChamp.type_champs.fetch(:departements), + TypeDeChamp.type_champs.fetch(:multiple_drop_down_list), TypeDeChamp.type_champs.fetch(:epci) ] diff --git a/config/locales/en.yml b/config/locales/en.yml index fad29d059..e39221915 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -471,6 +471,10 @@ en: attributes: value: not_in_options: "must be in the given options" + "champs/multiple_drop_down_list_champ": + attributes: + value: + not_in_options: "must be in the given options" "champs/region_champ": attributes: value: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index b1492cc79..ef2e6ab19 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -466,6 +466,10 @@ fr: attributes: value: not_in_options: "doit être dans les options proposées" + "champs/multiple_drop_down_list_champ": + attributes: + value: + not_in_options: "doit être dans les options proposées" "champs/region_champ": attributes: value: diff --git a/spec/controllers/instructeurs/dossiers_controller_spec.rb b/spec/controllers/instructeurs/dossiers_controller_spec.rb index 990b3a29c..b6e1af036 100644 --- a/spec/controllers/instructeurs/dossiers_controller_spec.rb +++ b/spec/controllers/instructeurs/dossiers_controller_spec.rb @@ -792,7 +792,7 @@ describe Instructeurs::DossiersController, type: :controller do champs_private_attributes: { '0': { id: champ_multiple_drop_down_list.id, - value: ['', 'un', 'deux'] + value: ['', 'val1', 'val2'] }, '1': { id: champ_datetime.id, @@ -813,7 +813,7 @@ describe Instructeurs::DossiersController, type: :controller do end it { - expect(champ_multiple_drop_down_list.value).to eq('["un", "deux"]') + 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('2019-12-21T13:17:00+01:00') @@ -839,7 +839,7 @@ describe Instructeurs::DossiersController, type: :controller do champs_public_attributes: { '0': { id: champ_multiple_drop_down_list.id, - value: ['', 'un', 'deux'] + value: ['', 'val1', 'val2'] } } } diff --git a/spec/factories/champ.rb b/spec/factories/champ.rb index 253247a8e..d1f4448f8 100644 --- a/spec/factories/champ.rb +++ b/spec/factories/champ.rb @@ -97,7 +97,7 @@ FactoryBot.define do factory :champ_multiple_drop_down_list, class: 'Champs::MultipleDropDownListChamp' do type_de_champ { association :type_de_champ_multiple_drop_down_list, procedure: dossier.procedure } - value { '["choix 1", "choix 2"]' } + value { '["val1", "val2"]' } end factory :champ_linked_drop_down_list, class: 'Champs::LinkedDropDownListChamp' do diff --git a/spec/models/champ_spec.rb b/spec/models/champ_spec.rb index bec9c3097..7cad128a7 100644 --- a/spec/models/champ_spec.rb +++ b/spec/models/champ_spec.rb @@ -117,7 +117,7 @@ describe Champ do # when using the old form, and the ChampsService Class # TODO: to remove context 'when the value is already deserialized' do - let(:value) { '["1", "2"]' } + let(:value) { '["val1", "val2"]' } it { expect(champ.value).to eq(value) } @@ -133,9 +133,9 @@ describe Champ do # GOTCHA context 'when the value is not already deserialized' do context 'when a choice is selected' do - let(:value) { '["", "1", "2"]' } + let(:value) { '["", "val1", "val2"]' } - it { expect(champ.value).to eq('["1", "2"]') } + it { expect(champ.value).to eq('["val1", "val2"]') } end context 'when all choices are removed' do diff --git a/spec/models/champs/multiple_drop_down_list_champ_spec.rb b/spec/models/champs/multiple_drop_down_list_champ_spec.rb new file mode 100644 index 000000000..08a78c77c --- /dev/null +++ b/spec/models/champs/multiple_drop_down_list_champ_spec.rb @@ -0,0 +1,38 @@ +describe Champs::MultipleDropDownListChamp do + describe 'validations' do + describe 'inclusion' do + let(:type_de_champ) { build(:type_de_champ_multiple_drop_down_list, drop_down_list_value: "val1\r\nval2\r\nval3") } + subject { build(:champ_multiple_drop_down_list, type_de_champ:, value:) } + + context 'when the value is nil' do + let(:value) { nil } + + it { is_expected.to be_valid } + end + + context 'when the value is an empty string' do + let(:value) { '' } + + it { is_expected.to be_valid } + end + + context 'when the value is an empty array' do + let(:value) { [] } + + it { is_expected.to be_valid } + end + + context 'when the value is included in the option list' do + let(:value) { ["val3", "val1"] } + + it { is_expected.to be_valid } + end + + context 'when the value is not included in the option list' do + let(:value) { ["totoro", "val1"] } + + it { is_expected.not_to be_valid } + end + end + end +end diff --git a/spec/models/prefill_params_spec.rb b/spec/models/prefill_params_spec.rb index ed3cfa001..bf9378ae0 100644 --- a/spec/models/prefill_params_spec.rb +++ b/spec/models/prefill_params_spec.rb @@ -189,6 +189,7 @@ RSpec.describe PrefillParams do it_behaves_like "a champ public value that is unauthorized", :siret, "value" it_behaves_like "a champ public value that is unauthorized", :rna, "value" it_behaves_like "a champ public value that is unauthorized", :annuaire_education, "value" + it_behaves_like "a champ public value that is unauthorized", :multiple_drop_down_list, ["value"] end private