diff --git a/app/components/types_de_champ_editor/conditions_errors_component.rb b/app/components/types_de_champ_editor/conditions_errors_component.rb index 4964d827f..d3500ab75 100644 --- a/app/components/types_de_champ_editor/conditions_errors_component.rb +++ b/app/components/types_de_champ_editor/conditions_errors_component.rb @@ -56,6 +56,10 @@ class TypesDeChampEditor::ConditionsErrorsComponent < ApplicationComponent right: right.to_s.downcase) in { type: :required_list } t('required_list', scope: '.errors') + in { type: :required_include, operator_name: "Logic::Eq" } + t("required_include.eq", scope: '.errors') + in { type: :required_include, operator_name: "Logic::NotEq" } + t("required_include.not_eq", scope: '.errors') else nil end diff --git a/app/components/types_de_champ_editor/conditions_errors_component/conditions_errors_component.en.yml b/app/components/types_de_champ_editor/conditions_errors_component/conditions_errors_component.en.yml index 5cdbcd70e..b80127786 100644 --- a/app/components/types_de_champ_editor/conditions_errors_component/conditions_errors_component.en.yml +++ b/app/components/types_de_champ_editor/conditions_errors_component/conditions_errors_component.en.yml @@ -1,9 +1,12 @@ --- -fr: +en: errors: not_available: "A targeted field is not available." unmanaged: "The field « %{libelle} » is a « %{type_champ} » and cannot be used as conditional source." incompatible: "The field « %{libelle} » is a « %{type_champ} ». It cannot be %{operator} « %{right} »." required_number: "« %{operator} » applies only to number." required_list: "The « include » operator only applies to simple or multiple choice." + required_include: + eq: "The « is » operator does not apply to multiple dropdown list. Select the « includes » operator." + not_eq: "The « is not » operator does not apply to multiple dropdown list." not_included: "« %{right} » is not included in « %{libelle} »." diff --git a/app/components/types_de_champ_editor/conditions_errors_component/conditions_errors_component.fr.yml b/app/components/types_de_champ_editor/conditions_errors_component/conditions_errors_component.fr.yml index 5be0ad01c..7062b6f93 100644 --- a/app/components/types_de_champ_editor/conditions_errors_component/conditions_errors_component.fr.yml +++ b/app/components/types_de_champ_editor/conditions_errors_component/conditions_errors_component.fr.yml @@ -6,4 +6,7 @@ fr: incompatible: "Le champ « %{libelle} » est de type « %{type_champ} ». Il ne peut pas être %{operator} « %{right} »." required_number: "« %{operator} » ne s'applique qu'à des nombres." required_list: "Lʼopérateur « inclus » ne s'applique qu'au choix simple ou multiple." + required_include: + eq: "Lʼopérateur « est » ne s'applique pas au choix multiple. Sélectionnez l’opérateur « contient »." + not_eq: "Lʼopérateur « n’est pas » ne s'applique pas au choix multiple." not_included: "« %{right} » ne fait pas partie de « %{libelle} »." diff --git a/app/models/logic/eq.rb b/app/models/logic/eq.rb index 0779be58e..da07341ce 100644 --- a/app/models/logic/eq.rb +++ b/app/models/logic/eq.rb @@ -20,6 +20,12 @@ class Logic::Eq < Logic::BinaryOperator stable_id: @left.stable_id, right: @right } + elsif @left.type(type_de_champs) == :enums + errors << { + type: :required_include, + stable_id: @left.try(:stable_id), + operator_name: self.class.name + } end errors + @left.errors(type_de_champs) + @right.errors(type_de_champs) diff --git a/spec/components/types_de_champ_editor/conditions_errors_component_spec.rb b/spec/components/types_de_champ_editor/conditions_errors_component_spec.rb index c76e53dc5..e829bc305 100644 --- a/spec/components/types_de_champ_editor/conditions_errors_component_spec.rb +++ b/spec/components/types_de_champ_editor/conditions_errors_component_spec.rb @@ -72,6 +72,22 @@ describe TypesDeChampEditor::ConditionsErrorsComponent, type: :component do it { expect(page).to have_content("« another choice » ne fait pas partie de « #{tdc.libelle} ».") } end + context 'when an eq operator applies to a multiple_drop_down' do + let(:tdc) { create(:type_de_champ_multiple_drop_down_list) } + let(:upper_tdcs) { [tdc] } + let(:conditions) { [ds_eq(champ_value(tdc.stable_id), constant(tdc.drop_down_list_enabled_non_empty_options.first))] } + + it { expect(page).to have_content("« est » ne s'applique pas au choix multiple.") } + end + + context 'when an not_eq operator applies to a multiple_drop_down' do + let(:tdc) { create(:type_de_champ_multiple_drop_down_list) } + let(:upper_tdcs) { [tdc] } + let(:conditions) { [ds_not_eq(champ_value(tdc.stable_id), constant(tdc.drop_down_list_enabled_non_empty_options.first))] } + + it { expect(page).to have_content("« n’est pas » ne s'applique pas au choix multiple.") } + end + context 'when target became unavailable but a right still references the value' do # Cf https://demarches-simplifiees.sentry.io/issues/3625488398/events/53164e105bc94d55a004d69f96d58fb2/?project=1429550 # However maybe we should not have empty at left with still a constant at right diff --git a/spec/models/logic/eq_spec.rb b/spec/models/logic/eq_spec.rb index fb9a9dee7..85464104b 100644 --- a/spec/models/logic/eq_spec.rb +++ b/spec/models/logic/eq_spec.rb @@ -17,6 +17,19 @@ describe Logic::Eq do } expect(ds_eq(constant(true), constant(1)).errors).to eq([expected]) end + + it do + multiple_drop_down = create(:type_de_champ_multiple_drop_down_list) + first_option = multiple_drop_down.drop_down_list_enabled_non_empty_options.first + + expected = { + operator_name: "Logic::Eq", + stable_id: multiple_drop_down.stable_id, + type: :required_include + } + + expect(ds_eq(champ_value(multiple_drop_down.stable_id), constant(first_option)).errors([multiple_drop_down])).to eq([expected]) + end end describe '#==' do diff --git a/spec/models/logic/not_eq_spec.rb b/spec/models/logic/not_eq_spec.rb index b119e75f5..9125a62a2 100644 --- a/spec/models/logic/not_eq_spec.rb +++ b/spec/models/logic/not_eq_spec.rb @@ -17,6 +17,19 @@ describe Logic::NotEq do } expect(ds_not_eq(constant(true), constant(1)).errors).to eq([expected]) end + + it do + multiple_drop_down = create(:type_de_champ_multiple_drop_down_list) + first_option = multiple_drop_down.drop_down_list_enabled_non_empty_options.first + + expected = { + operator_name: "Logic::NotEq", + stable_id: multiple_drop_down.stable_id, + type: :required_include + } + + expect(ds_not_eq(champ_value(multiple_drop_down.stable_id), constant(first_option)).errors([multiple_drop_down])).to eq([expected]) + end end describe '#==' do