Merge pull request #9423 from demarches-simplifiees/can-route-with-not-equals-routing-rules
ETQ admin je peux router avec des règles dont l'opérateur est "n'est pas"
This commit is contained in:
commit
0c004fd4e5
6 changed files with 137 additions and 26 deletions
|
@ -17,6 +17,10 @@ class Procedure::OneGroupeManagementComponent < ApplicationComponent
|
|||
@groupe_instructeur.routing_rule&.right || empty
|
||||
end
|
||||
|
||||
def operator_name
|
||||
@groupe_instructeur.routing_rule&.class&.name || empty
|
||||
end
|
||||
|
||||
def targeted_champ_tag
|
||||
select_tag(
|
||||
'targeted_champ',
|
||||
|
@ -39,6 +43,21 @@ class Procedure::OneGroupeManagementComponent < ApplicationComponent
|
|||
.map { |tdc| [tdc.libelle, champ_value(tdc.stable_id).to_json] }
|
||||
end
|
||||
|
||||
def operator_tag
|
||||
select_tag('operator_name',
|
||||
options_for_select(
|
||||
options_for_operator_tag,
|
||||
selected: operator_name
|
||||
),
|
||||
class: 'fr-select')
|
||||
end
|
||||
|
||||
def options_for_operator_tag
|
||||
[Eq, NotEq]
|
||||
.map(&:name)
|
||||
.map { |name| [t(name, scope: 'logic.operators'), name] }
|
||||
end
|
||||
|
||||
def value_tag
|
||||
select_tag(
|
||||
'value',
|
||||
|
|
|
@ -40,7 +40,8 @@
|
|||
.fr-mr-2w.no-wrap si le champ
|
||||
.target.fr-mr-2w
|
||||
= targeted_champ_tag
|
||||
.operator.fr-mr-2w.no-wrap est égal à
|
||||
.operator.fr-mr-2w.no-wrap
|
||||
= operator_tag
|
||||
.value
|
||||
= value_tag
|
||||
.fr-hint-text
|
||||
|
|
|
@ -9,7 +9,13 @@ module Administrateurs
|
|||
|
||||
right = targeted_champ_changed? ? empty : value
|
||||
|
||||
groupe_instructeur.update!(routing_rule: ds_eq(left, right))
|
||||
new_routing_rule = case operator_name
|
||||
when Eq.name
|
||||
ds_eq(left, right)
|
||||
when NotEq.name
|
||||
ds_not_eq(left, right)
|
||||
end
|
||||
groupe_instructeur.update!(routing_rule: new_routing_rule)
|
||||
end
|
||||
|
||||
def update_defaut_groupe_instructeur
|
||||
|
@ -27,6 +33,10 @@ module Administrateurs
|
|||
Logic.from_json(params[:targeted_champ])
|
||||
end
|
||||
|
||||
def operator_name
|
||||
params[:operator_name]
|
||||
end
|
||||
|
||||
def value
|
||||
Logic.from_json(params[:value])
|
||||
end
|
||||
|
|
|
@ -73,9 +73,12 @@ class GroupeInstructeur < ApplicationRecord
|
|||
end
|
||||
|
||||
def invalid_rule?
|
||||
rule = routing_rule
|
||||
return true if !(rule.is_a?(Logic::Eq) && rule.left.is_a?(Logic::ChampValue) && rule.right.is_a?(Logic::Constant))
|
||||
return true if !routing_rule_matches_tdc?
|
||||
!valid_rule?
|
||||
end
|
||||
|
||||
def valid_rule?
|
||||
return false if routing_rule.nil?
|
||||
([routing_rule.left, routing_rule, routing_rule.right] in [ChampValue, Eq | NotEq, Constant]) && routing_rule_matches_tdc?
|
||||
end
|
||||
|
||||
def non_unique_rule?
|
||||
|
|
|
@ -11,11 +11,15 @@ describe Administrateurs::RoutingController, type: :controller do
|
|||
{
|
||||
procedure_id: procedure.id,
|
||||
targeted_champ: champ_value(drop_down_tdc.stable_id).to_json,
|
||||
operator_name: operator_name,
|
||||
value: empty.to_json,
|
||||
groupe_instructeur_id: gi_2.id
|
||||
}
|
||||
end
|
||||
|
||||
context 'with Eq operator' do
|
||||
let(:operator_name) { Logic::Eq.name }
|
||||
|
||||
before do
|
||||
post :update, params: params, format: :turbo_stream
|
||||
end
|
||||
|
@ -50,6 +54,44 @@ describe Administrateurs::RoutingController, type: :controller do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with NotEq operator' do
|
||||
let(:operator_name) { Logic::NotEq.name }
|
||||
|
||||
before do
|
||||
post :update, params: params, format: :turbo_stream
|
||||
end
|
||||
|
||||
it do
|
||||
expect(gi_2.reload.routing_rule).to eq(ds_not_eq(champ_value(drop_down_tdc.stable_id), empty))
|
||||
end
|
||||
|
||||
context '#update value' do
|
||||
let(:value_updated_params) { params.merge(value: constant('Lyon').to_json) }
|
||||
|
||||
before do
|
||||
post :update, params: value_updated_params, format: :turbo_stream
|
||||
end
|
||||
|
||||
it do
|
||||
expect(gi_2.reload.routing_rule).to eq(ds_not_eq(champ_value(drop_down_tdc.stable_id), constant('Lyon')))
|
||||
end
|
||||
|
||||
context 'targeted champ changed' do
|
||||
let(:last_tdc) { procedure.draft_revision.types_de_champ.last }
|
||||
|
||||
before do
|
||||
targeted_champ_updated_params = value_updated_params.merge(targeted_champ: champ_value(last_tdc.stable_id).to_json)
|
||||
post :update, params: targeted_champ_updated_params, format: :turbo_stream
|
||||
end
|
||||
|
||||
it do
|
||||
expect(gi_2.reload.routing_rule).to eq(ds_not_eq(champ_value(last_tdc.stable_id), empty))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#update_defaut_groupe_instructeur" do
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:gi_2) { create(:groupe_instructeur, label: 'groupe 2', procedure: procedure) }
|
||||
|
|
|
@ -4,7 +4,7 @@ describe RoutingEngine, type: :model do
|
|||
describe '.compute' do
|
||||
let(:dossier) { create(:dossier, procedure:) }
|
||||
let(:defaut_groupe) { procedure.defaut_groupe_instructeur }
|
||||
let(:gi_2) { procedure.groupe_instructeurs.find_by(label: 'a second group') }
|
||||
let(:gi_2) { procedure.groupe_instructeurs.create(label: 'a second group') }
|
||||
|
||||
subject do
|
||||
RoutingEngine.compute(dossier)
|
||||
|
@ -15,7 +15,6 @@ describe RoutingEngine, type: :model do
|
|||
let(:procedure) do
|
||||
create(:procedure,
|
||||
types_de_champ_public: [{ type: :drop_down_list, libelle: 'Votre ville', options: ['Paris', 'Lyon', 'Marseille'] }]).tap do |p|
|
||||
p.groupe_instructeurs.create(label: 'a second group')
|
||||
p.groupe_instructeurs.create(label: 'a third group')
|
||||
end
|
||||
end
|
||||
|
@ -29,7 +28,7 @@ describe RoutingEngine, type: :model do
|
|||
context 'without any matching rules' do
|
||||
before do
|
||||
procedure.groupe_instructeurs.each do |gi|
|
||||
gi.update(routing_rule: constant(false))
|
||||
gi.update(routing_rule: ds_eq(constant(false), constant(false)))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -60,12 +59,23 @@ describe RoutingEngine, type: :model do
|
|||
|
||||
it { is_expected.to eq(defaut_groupe) }
|
||||
end
|
||||
|
||||
context 'with a non equals rule' do
|
||||
before do
|
||||
gi_2.update(routing_rule: ds_not_eq(champ_value(drop_down_tdc.stable_id), constant('Lyon')))
|
||||
dossier.champs.first.update(value: 'Paris')
|
||||
end
|
||||
|
||||
it do
|
||||
is_expected.not_to eq(defaut_groupe)
|
||||
is_expected.to eq(gi_2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a departements type de champ' do
|
||||
let(:procedure) do
|
||||
create(:procedure, types_de_champ_public: [{ type: :departements }]).tap do |p|
|
||||
p.groupe_instructeurs.create(label: 'a second group')
|
||||
p.groupe_instructeurs.create(label: 'a third group')
|
||||
end
|
||||
end
|
||||
|
@ -81,5 +91,31 @@ describe RoutingEngine, type: :model do
|
|||
it { is_expected.to eq(gi_2) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'routing rules priorities' do
|
||||
let(:procedure) do
|
||||
create(:procedure,
|
||||
types_de_champ_public: [{ type: :drop_down_list, libelle: 'Ville', options: ['Paris', 'Lyon', 'Marseille'] }]).tap do |p|
|
||||
p.groupe_instructeurs.create(label: 'c')
|
||||
end
|
||||
end
|
||||
|
||||
let(:drop_down_tdc) { procedure.draft_revision.types_de_champ.first }
|
||||
|
||||
let!(:gi_3) { procedure.groupe_instructeurs.find_by(label: 'c') }
|
||||
|
||||
context 'not eq rule coming first' do
|
||||
before do
|
||||
defaut_groupe.update(label: 'a')
|
||||
gi_2.update(label: 'b', routing_rule: ds_not_eq(champ_value(drop_down_tdc.stable_id), constant('Lyon')))
|
||||
gi_3.update(routing_rule: ds_eq(champ_value(drop_down_tdc.stable_id), constant('Marseille')))
|
||||
dossier.champs.first.update(value: 'Marseille')
|
||||
end
|
||||
|
||||
it 'computes by groups label order' do
|
||||
is_expected.to eq(gi_2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue