diff --git a/app/components/conditions/conditions_component.rb b/app/components/conditions/conditions_component.rb index 833e2c89d..7cfd3f22b 100644 --- a/app/components/conditions/conditions_component.rb +++ b/app/components/conditions/conditions_component.rb @@ -99,7 +99,8 @@ class Conditions::ConditionsComponent < ApplicationComponent ] when ChampValue::CHAMP_VALUE_TYPE.fetch(:enums) [ - [t(IncludeOperator.name, scope: 'logic.operators'), IncludeOperator.name] + [t(IncludeOperator.name, scope: 'logic.operators'), IncludeOperator.name], + [t(ExcludeOperator.name, scope: 'logic.operators'), ExcludeOperator.name] ] when ChampValue::CHAMP_VALUE_TYPE.fetch(:number) [Eq, LessThan, GreaterThan, LessThanEq, GreaterThanEq] diff --git a/app/models/groupe_instructeur.rb b/app/models/groupe_instructeur.rb index e9b67ac6c..f7ecf059d 100644 --- a/app/models/groupe_instructeur.rb +++ b/app/models/groupe_instructeur.rb @@ -92,7 +92,7 @@ class GroupeInstructeur < ApplicationRecord end def valid_rule_line?(rule) - ([rule.left, rule, rule.right] in [ChampValue, (LessThan | LessThanEq | Eq | NotEq | GreaterThanEq | GreaterThan | IncludeOperator), Constant]) && routing_rule_matches_tdc?(rule) + ([rule.left, rule, rule.right] in [ChampValue, (LessThan | LessThanEq | Eq | NotEq | GreaterThanEq | GreaterThan | IncludeOperator | ExcludeOperator), Constant]) && routing_rule_matches_tdc?(rule) end def non_unique_rule? diff --git a/app/models/logic.rb b/app/models/logic.rb index 5c3f1c25c..7c4c7ba56 100644 --- a/app/models/logic.rb +++ b/app/models/logic.rb @@ -8,7 +8,7 @@ module Logic end def self.class_from_name(name) - [ChampValue, Constant, Empty, LessThan, LessThanEq, Eq, NotEq, GreaterThanEq, GreaterThan, EmptyOperator, IncludeOperator, And, Or] + [ChampValue, Constant, Empty, LessThan, LessThanEq, Eq, NotEq, GreaterThanEq, GreaterThan, EmptyOperator, IncludeOperator, ExcludeOperator, And, Or] .find { |c| c.name == name } end @@ -88,6 +88,8 @@ module Logic def ds_include(left, right) = Logic::IncludeOperator.new(left, right) + def ds_exclude(left, right) = Logic::ExcludeOperator.new(left, right) + def constant(value) = Logic::Constant.new(value) def champ_value(stable_id) = Logic::ChampValue.new(stable_id) diff --git a/app/models/logic/exclude_operator.rb b/app/models/logic/exclude_operator.rb new file mode 100644 index 000000000..8addb7d0a --- /dev/null +++ b/app/models/logic/exclude_operator.rb @@ -0,0 +1,3 @@ +class Logic::ExcludeOperator < Logic::IncludeOperator + def operation = :exclude? +end diff --git a/config/locales/models/logic/fr.yml b/config/locales/models/logic/fr.yml index 7f3045c3d..5d5075cc1 100644 --- a/config/locales/models/logic/fr.yml +++ b/config/locales/models/logic/fr.yml @@ -14,3 +14,4 @@ fr: 'Logic::Or': Ou 'Logic::NotEq': N’est pas 'Logic::IncludeOperator': Contient + 'Logic::ExcludeOperator': Ne contient pas diff --git a/spec/models/logic/exclude_operator_spec.rb b/spec/models/logic/exclude_operator_spec.rb new file mode 100644 index 000000000..b4c1248b7 --- /dev/null +++ b/spec/models/logic/exclude_operator_spec.rb @@ -0,0 +1,29 @@ +describe Logic::ExcludeOperator do + include Logic + + let(:champ) { create(:champ_multiple_drop_down_list, value: '["val1", "val2"]') } + + describe '#compute' do + it { expect(ds_exclude(champ_value(champ.stable_id), constant('val1')).compute([champ])).to be(false) } + it { expect(ds_exclude(champ_value(champ.stable_id), constant('something else')).compute([champ])).to be(true) } + end + + describe '#errors' do + it { expect(ds_exclude(champ_value(champ.stable_id), constant('val1')).errors([champ.type_de_champ])).to be_empty } + it do + expected = { + right: constant('something else'), + stable_id: champ.stable_id, + type: :not_included + } + + expect(ds_exclude(champ_value(champ.stable_id), constant('something else')).errors([champ.type_de_champ])).to eq([expected]) + end + + it { expect(ds_exclude(constant(1), constant('val1')).errors([])).to eq([{ type: :required_list }]) } + end + + describe '#==' do + it { expect(ds_include(champ_value(champ.stable_id), constant('val1'))).to eq(ds_include(champ_value(champ.stable_id), constant('val1'))) } + end +end