tech(clean): simplify implementation of eligibilite rules, code, enhance wording and test coverage
This commit is contained in:
parent
a011576757
commit
f819da8921
29 changed files with 161 additions and 219 deletions
|
@ -57,5 +57,14 @@ form.form > .conditionnel {
|
||||||
select.alert {
|
select.alert {
|
||||||
border-color: $dark-red;
|
border-color: $dark-red;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,30 @@
|
||||||
%div{ id: dom_id(@draft_revision, :ineligibilite_rules) }
|
%div{ id: dom_id(@draft_revision, :ineligibilite_rules) }
|
||||||
= render Procedure::PendingRepublishComponent.new(procedure: @draft_revision.procedure, render_if: pending_changes?)
|
= render Procedure::PendingRepublishComponent.new(procedure: @draft_revision.procedure, render_if: pending_changes?)
|
||||||
= render Conditions::ConditionsErrorsComponent.new(conditions: condition_per_row, source_tdcs: @source_tdcs)
|
= render Conditions::ConditionsErrorsComponent.new(conditions: condition_per_row, source_tdcs: @source_tdcs)
|
||||||
%fieldset.fr-fieldset
|
.fr-fieldset
|
||||||
%legend.fr-mx-1w.fr-label.fr-py-0.fr-mb-1w.fr-mt-2w
|
= form_for(@draft_revision, url: change_admin_procedure_ineligibilite_rules_path(@draft_revision.procedure_id), html: { id: 'ineligibilite_form', class: 'width-100' }) do |f|
|
||||||
Règles d’inéligibilité
|
.fr-fieldset__element
|
||||||
%span.fr-hint-text Vous pouvez utiliser 1 ou plusieurs critère pour bloquer le dépot
|
.fr-toggle.fr-toggle--label-left
|
||||||
|
= f.check_box :ineligibilite_enabled, class: 'fr-toggle__input', data: @opt
|
||||||
|
= f.label :ineligibilite_enabled, "Bloquer le dépôt des dossiers répondant à des conditions d’inéligibilité", data: { 'fr-checked-label': "Activé", 'fr-unchecked-label': "Désactivé" }, class: 'fr-toggle__label'
|
||||||
|
|
||||||
|
.fr-fieldset__element= render Dsfr::InputComponent.new(form: f, attribute: :ineligibilite_message, input_type: :text_area, opts: {rows: 5})
|
||||||
|
|
||||||
|
.fr-mx-1w.fr-label.fr-py-0.fr-mb-1w.fr-mt-2w
|
||||||
|
Conditions d’inéligibilité
|
||||||
|
%span.fr-hint-text Vous pouvez utiliser une ou plusieurs condtions pour bloquer le dépot.
|
||||||
.fr-fieldset__element
|
.fr-fieldset__element
|
||||||
= form_tag admin_procedure_ineligibilite_rules_path(@draft_revision.procedure_id), method: :patch, data: { turbo: true, controller: 'autosave' }, class: 'form width-100' do
|
= form_tag admin_procedure_ineligibilite_rules_path(@draft_revision.procedure_id), method: :patch, data: { turbo: true, controller: 'autosave' }, class: 'form width-100' do
|
||||||
.conditionnel.width-100
|
.conditionnel.width-100
|
||||||
%table.condition-table
|
%table.condition-table
|
||||||
%thead
|
- if rows.size > 0
|
||||||
%tr
|
%thead
|
||||||
%th.fr-pt-0.far-left
|
%tr
|
||||||
%th.fr-pt-0.target Champ Cible
|
%th.fr-pt-0.far-left
|
||||||
%th.fr-pt-0.operator Opérateur
|
%th.fr-pt-0.target Champ Cible
|
||||||
%th.fr-pt-0.value Valeur
|
%th.fr-pt-0.operator Opérateur
|
||||||
%th.fr-pt-0.delete-column
|
%th.fr-pt-0.value Valeur
|
||||||
|
%th.fr-pt-0.delete-column
|
||||||
%tbody
|
%tbody
|
||||||
- rows.each.with_index do |(targeted_champ, operator_name, value), row_index|
|
- rows.each.with_index do |(targeted_champ, operator_name, value), row_index|
|
||||||
%tr
|
%tr
|
||||||
|
@ -28,15 +37,13 @@
|
||||||
%tr
|
%tr
|
||||||
%td.text-right{ colspan: 5 }= add_condition_tag
|
%td.text-right{ colspan: 5 }= add_condition_tag
|
||||||
|
|
||||||
|
.padded-fixed-footer
|
||||||
|
.fixed-footer
|
||||||
= form_for(@draft_revision, url: change_admin_procedure_ineligibilite_rules_path(@draft_revision.procedure_id)) do |f|
|
.fr-container
|
||||||
.fr-fieldset__element= render Dsfr::InputComponent.new(form: f, attribute: :ineligibilite_message, input_type: :text_area, opts: {rows: 5})
|
.fr-grid-row.fr-col-offset-md-2.fr-col-md-8
|
||||||
.fr-fieldset__element
|
.fr-col-12
|
||||||
.fr-toggle
|
%ul.fr-btns-group.fr-btns-group--inline-md
|
||||||
= f.check_box :ineligibilite_enabled, class: 'fr-toggle__input', data: @opt
|
%li
|
||||||
= f.label :ineligibilite_enabled, "Inéligibilité des dossiers", data: { 'fr-checked-label': "Actif", 'fr-unchecked-label': "Inactif" }, class: 'fr-toggle__label'
|
= link_to "Annuler et revenir à l'écran de gestion", admin_procedure_path(id: @draft_revision.procedure), class: 'fr-btn fr-btn--secondary', data: { confirm: 'Si vous avez fait des modifications elles ne seront pas sauvegardées.'}
|
||||||
%p.fr-hint-text Passer l’intérrupteur sur activé pour que les critères d’inéligibilité configurés s'appliquent
|
%li
|
||||||
|
= button_tag "Enregistrer", class: "fr-btn", form: 'ineligibilite_form'
|
||||||
|
|
||||||
= render Procedure::FixedFooterComponent.new(procedure: @draft_revision.procedure, form: f, extra_class_names: 'fr-col-offset-md-2 fr-col-md-8')
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class Dossiers::EditFooterComponent < ApplicationComponent
|
class Dossiers::EditFooterComponent < ApplicationComponent
|
||||||
delegate :can_passer_en_construction?, :ineligibilite_rules_computable?, to: :@dossier
|
delegate :can_passer_en_construction?, to: :@dossier
|
||||||
|
|
||||||
def initialize(dossier:, annotation:)
|
def initialize(dossier:, annotation:)
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
|
@ -27,7 +27,7 @@ class Dossiers::EditFooterComponent < ApplicationComponent
|
||||||
def submit_draft_button_options
|
def submit_draft_button_options
|
||||||
{
|
{
|
||||||
class: 'fr-btn fr-btn--sm',
|
class: 'fr-btn fr-btn--sm',
|
||||||
disabled: !owner? || ineligibilite_rules_invalid?,
|
disabled: !owner? || !can_passer_en_construction?,
|
||||||
method: :post,
|
method: :post,
|
||||||
data: { 'disable-with': t('.submitting'), controller: 'autosave-submit', turbo_force: :server }
|
data: { 'disable-with': t('.submitting'), controller: 'autosave-submit', turbo_force: :server }
|
||||||
}
|
}
|
||||||
|
@ -36,17 +36,13 @@ class Dossiers::EditFooterComponent < ApplicationComponent
|
||||||
def submit_en_construction_button_options
|
def submit_en_construction_button_options
|
||||||
{
|
{
|
||||||
class: 'fr-btn fr-btn--sm',
|
class: 'fr-btn fr-btn--sm',
|
||||||
disabled: ineligibilite_rules_invalid?,
|
disabled: !can_passer_en_construction?,
|
||||||
method: :post,
|
method: :post,
|
||||||
data: { 'disable-with': t('.submitting'), controller: 'autosave-submit', turbo_force: :server },
|
data: { 'disable-with': t('.submitting'), controller: 'autosave-submit', turbo_force: :server },
|
||||||
form: { id: "form-submit-en-construction" }
|
form: { id: "form-submit-en-construction" }
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def ineligibilite_rules_invalid?
|
|
||||||
ineligibilite_rules_computable? && !can_passer_en_construction?
|
|
||||||
end
|
|
||||||
|
|
||||||
def render?
|
def render?
|
||||||
!@dossier.for_procedure_preview?
|
!@dossier.for_procedure_preview?
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
= render Dossiers::AutosaveFooterComponent.new(dossier: @dossier, annotation: annotation?)
|
= render Dossiers::AutosaveFooterComponent.new(dossier: @dossier, annotation: annotation?)
|
||||||
|
|
||||||
- if !annotation? && @dossier.can_transition_to_en_construction?
|
- if !annotation? && @dossier.can_transition_to_en_construction?
|
||||||
- if ineligibilite_rules_invalid?
|
- if !can_passer_en_construction?
|
||||||
= link_to t('.submit_disabled'), "#", disabled_submit_buttons_options
|
= link_to t('.submit_disabled'), "#", disabled_submit_buttons_options
|
||||||
= button_to t('.submit'), brouillon_dossier_url(@dossier), submit_draft_button_options
|
= button_to t('.submit'), brouillon_dossier_url(@dossier), submit_draft_button_options
|
||||||
|
|
||||||
- if @dossier.forked_with_changes?
|
- if @dossier.forked_with_changes?
|
||||||
- if ineligibilite_rules_invalid?
|
- if !can_passer_en_construction?
|
||||||
= link_to t('.submit_disabled'), "#", disabled_submit_buttons_options
|
= link_to t('.submit_disabled'), "#", disabled_submit_buttons_options
|
||||||
= button_to t('.submit_changes'), modifier_dossier_url(@dossier.editing_fork_origin), submit_en_construction_button_options
|
= button_to t('.submit_changes'), modifier_dossier_url(@dossier.editing_fork_origin), submit_en_construction_button_options
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class Dossiers::InvalidIneligibiliteRulesComponent < ApplicationComponent
|
class Dossiers::InvalidIneligibiliteRulesComponent < ApplicationComponent
|
||||||
delegate :can_passer_en_construction?, :ineligibilite_rules_computable?, to: :@dossier
|
delegate :can_passer_en_construction?, to: :@dossier
|
||||||
|
|
||||||
def initialize(dossier:)
|
def initialize(dossier:)
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
|
@ -7,7 +7,7 @@ class Dossiers::InvalidIneligibiliteRulesComponent < ApplicationComponent
|
||||||
end
|
end
|
||||||
|
|
||||||
def render?
|
def render?
|
||||||
ineligibilite_rules_computable? && !can_passer_en_construction?
|
!can_passer_en_construction?
|
||||||
end
|
end
|
||||||
|
|
||||||
def error_message
|
def error_message
|
||||||
|
|
|
@ -6,7 +6,7 @@ class Procedure::Card::IneligibiliteDossierComponent < ApplicationComponent
|
||||||
def ready?
|
def ready?
|
||||||
@procedure.draft_revision
|
@procedure.draft_revision
|
||||||
.conditionable_types_de_champ
|
.conditionable_types_de_champ
|
||||||
.present?
|
.present? && @procedure.draft_revision.ineligibilite_enabled
|
||||||
end
|
end
|
||||||
|
|
||||||
def error?
|
def error?
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
fr:
|
fr:
|
||||||
title: Inéligibilité des dossiers
|
title: Inéligibilité des dossiers
|
||||||
state:
|
state:
|
||||||
pending: Champs à configurer
|
pending: Désactivé
|
||||||
ready: À configurer
|
ready: À configurer
|
||||||
completed: Activé
|
completed: Activé
|
||||||
subtitle: Gérez vos critères d’inéligibilité en fonction des champs du formulaire
|
subtitle: Gérez vos conditions d’inéligibilité en fonction des champs du formulaire
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
= link_to edit_admin_procedure_ineligibilite_rules_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
= link_to edit_admin_procedure_ineligibilite_rules_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
||||||
.fr-tile__body.flex.column.align-center.justify-between
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
- if !ready?
|
- if !ready?
|
||||||
%p.fr-badge.fr-badge--warning= t('.state.pending')
|
%p.fr-badge.fr-badge= t('.state.pending')
|
||||||
- elsif error?
|
- elsif error?
|
||||||
%p.fr-badge.fr-badge--error À modifier
|
%p.fr-badge.fr-badge--error À modifier
|
||||||
- elsif !completed?
|
|
||||||
%p.fr-badge.fr-badge--info= t('.state.ready')
|
|
||||||
- else
|
- else
|
||||||
%p.fr-badge.fr-badge--success= t('.state.completed')
|
%p.fr-badge.fr-badge--success= t('.state.completed')
|
||||||
%div
|
%div
|
||||||
|
|
|
@ -302,13 +302,10 @@ module Users
|
||||||
def update
|
def update
|
||||||
@dossier = dossier.en_construction? ? dossier.find_editing_fork(dossier.user) : dossier
|
@dossier = dossier.en_construction? ? dossier.find_editing_fork(dossier.user) : dossier
|
||||||
@dossier = dossier_with_champs(pj_template: false)
|
@dossier = dossier_with_champs(pj_template: false)
|
||||||
@ineligibilite_rules_was_computable = @dossier.ineligibilite_rules_computable?
|
|
||||||
@can_passer_en_construction_was = @dossier.can_passer_en_construction?
|
@can_passer_en_construction_was = @dossier.can_passer_en_construction?
|
||||||
update_dossier_and_compute_errors
|
update_dossier_and_compute_errors
|
||||||
@dossier.index_search_terms_later if @dossier.errors.empty?
|
@dossier.index_search_terms_later if @dossier.errors.empty?
|
||||||
@ineligibilite_rules_is_computable = @dossier.ineligibilite_rules_computable?
|
|
||||||
@can_passer_en_construction_is = @dossier.can_passer_en_construction?
|
@can_passer_en_construction_is = @dossier.can_passer_en_construction?
|
||||||
@ineligibilite_rules_computable_changed = !@ineligibilite_rules_was_computable && @ineligibilite_rules_is_computable
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.turbo_stream do
|
format.turbo_stream do
|
||||||
@to_show, @to_hide, @to_update = champs_to_turbo_update(champs_public_attributes_params, dossier.champs.filter(&:public?))
|
@to_show, @to_hide, @to_update = champs_to_turbo_update(champs_public_attributes_params, dossier.champs.filter(&:public?))
|
||||||
|
|
|
@ -940,12 +940,9 @@ class Dossier < ApplicationRecord
|
||||||
.filter(&:visible?)
|
.filter(&:visible?)
|
||||||
.filter(&:mandatory_blank?)
|
.filter(&:mandatory_blank?)
|
||||||
.map do |champ|
|
.map do |champ|
|
||||||
errors.import(champ.errors.add(:value, :missing))
|
champ.errors.add(:value, :missing)
|
||||||
end
|
end
|
||||||
end
|
.each { errors.import(_1) }
|
||||||
|
|
||||||
def ineligibilite_rules_computable?
|
|
||||||
revision.ineligibilite_rules_computable?(champs_for_revision(scope: :public))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def demander_un_avis!(avis)
|
def demander_un_avis!(avis)
|
||||||
|
|
|
@ -7,12 +7,5 @@ class Logic::And < Logic::NAryOperator
|
||||||
@operands.map { |operand| operand.compute(champs) }.all?
|
@operands.map { |operand| operand.compute(champs) }.all?
|
||||||
end
|
end
|
||||||
|
|
||||||
def computable?(champs = [])
|
|
||||||
return true if sources.blank?
|
|
||||||
|
|
||||||
champs.filter { _1.stable_id.in?(sources) && _1.visible? }
|
|
||||||
.all? { _1.value.present? }
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s(type_de_champs) = "(#{@operands.map { |o| o.to_s(type_de_champs) }.join(' && ')})"
|
def to_s(type_de_champs) = "(#{@operands.map { |o| o.to_s(type_de_champs) }.join(' && ')})"
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,15 +42,6 @@ class Logic::BinaryOperator < Logic::Term
|
||||||
l&.send(operation, r) || false
|
l&.send(operation, r) || false
|
||||||
end
|
end
|
||||||
|
|
||||||
def computable?(champs = [])
|
|
||||||
return true if sources.blank?
|
|
||||||
|
|
||||||
visible_champs_sources = champs.filter { _1.stable_id.in?(sources) && _1.visible? }
|
|
||||||
|
|
||||||
return false if visible_champs_sources.size != sources.size
|
|
||||||
visible_champs_sources.all? { _1.value.present? }
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s(type_de_champs) = "(#{@left.to_s(type_de_champs)} #{operation} #{@right.to_s(type_de_champs)})"
|
def to_s(type_de_champs) = "(#{@left.to_s(type_de_champs)} #{operation} #{@right.to_s(type_de_champs)})"
|
||||||
|
|
||||||
def ==(other)
|
def ==(other)
|
||||||
|
|
|
@ -7,15 +7,5 @@ class Logic::Or < Logic::NAryOperator
|
||||||
@operands.map { |operand| operand.compute(champs) }.any?
|
@operands.map { |operand| operand.compute(champs) }.any?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def computable?(champs = [])
|
|
||||||
return true if sources.blank?
|
|
||||||
|
|
||||||
visible_champs_sources = champs.filter { _1.stable_id.in?(sources) && _1.visible? }
|
|
||||||
|
|
||||||
return false if visible_champs_sources.blank?
|
|
||||||
visible_champs_sources.all? { _1.value.present? } || compute(visible_champs_sources)
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s(type_de_champs = []) = "(#{@operands.map { |o| o.to_s(type_de_champs) }.join(' || ')})"
|
def to_s(type_de_champs = []) = "(#{@operands.map { |o| o.to_s(type_de_champs) }.join(' || ')})"
|
||||||
end
|
end
|
||||||
|
|
|
@ -269,12 +269,6 @@ class ProcedureRevision < ApplicationRecord
|
||||||
types_de_champ_for(scope: :public).filter(&:conditionable?)
|
types_de_champ_for(scope: :public).filter(&:conditionable?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def ineligibilite_rules_computable?(champs)
|
|
||||||
ineligibilite_enabled && ineligibilite_rules&.computable?(champs)
|
|
||||||
ensure
|
|
||||||
champs.map(&:reset_visible) # otherwise @visible is cached, then dossier can be updated. champs are not updated
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def compute_estimated_fill_duration
|
def compute_estimated_fill_duration
|
||||||
|
@ -496,13 +490,6 @@ class ProcedureRevision < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def ineligibilite_rules_are_valid?
|
|
||||||
if ineligibilite_rules
|
|
||||||
ineligibilite_rules.errors(types_de_champ_for(scope: :public).to_a)
|
|
||||||
.each { errors.add(:ineligibilite_rules, :invalid) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def replace_type_de_champ_by_clone(coordinate)
|
def replace_type_de_champ_by_clone(coordinate)
|
||||||
cloned_type_de_champ = coordinate.type_de_champ.deep_clone do |original, kopy|
|
cloned_type_de_champ = coordinate.type_de_champ.deep_clone do |original, kopy|
|
||||||
ClonePiecesJustificativesService.clone_attachments(original, kopy)
|
ClonePiecesJustificativesService.clone_attachments(original, kopy)
|
||||||
|
|
|
@ -12,17 +12,17 @@
|
||||||
= render Dsfr::AlertComponent.new(title: nil, size: :sm, state: :info, heading_level: 'h2', extra_class_names: 'fr-my-2w') do |c|
|
= render Dsfr::AlertComponent.new(title: nil, size: :sm, state: :info, heading_level: 'h2', extra_class_names: 'fr-my-2w') do |c|
|
||||||
- c.with_body do
|
- c.with_body do
|
||||||
%p
|
%p
|
||||||
Les dossiers répondant à vos critères d’inéligibilité ne pourront pas être déposés. Plus d’informations sur l’inéligibilité des dossiers dans la
|
Les dossiers répondant à vos conditions d’inéligibilité ne pourront pas être déposés. Plus d’informations sur l’inéligibilité des dossiers dans la
|
||||||
= link_to('doc', ELIGIBILITE_URL, title: "Document sur l’inéligibilité des dossiers", **external_link_attributes)
|
= link_to('doc', ELIGIBILITE_URL, title: "Document sur l’inéligibilité des dossiers", **external_link_attributes)
|
||||||
|
|
||||||
- if !@procedure.draft_revision.conditionable_types_de_champ.present?
|
- if !@procedure.draft_revision.conditionable_types_de_champ.present?
|
||||||
%p.fr-mt-2w.fr-mb-2w
|
%p.fr-mt-2w.fr-mb-2w
|
||||||
Pour configurer l’inéligibilité des dossiers, votre formulaire doit comporter au moins un champ supportant les critères d’inéligibilité. Il vous faut donc ajouter au moins un des champs suivant à votre formulaire :
|
Pour configurer l’inéligibilité des dossiers, votre formulaire doit comporter au moins un champ supportant les conditions d’inéligibilité. Il vous faut donc ajouter au moins un des champs suivant à votre formulaire :
|
||||||
%ul
|
%ul
|
||||||
- Logic::ChampValue::MANAGED_TYPE_DE_CHAMP.values.each do
|
- Logic::ChampValue::MANAGED_TYPE_DE_CHAMP.values.each do
|
||||||
%li= "« #{t(_1, scope: [:activerecord, :attributes, :type_de_champ, :type_champs])} »"
|
%li= "« #{t(_1, scope: [:activerecord, :attributes, :type_de_champ, :type_champs])} »"
|
||||||
%p.fr-mt-2w
|
%p.fr-mt-2w
|
||||||
= link_to 'Ajouter un champ supportant les critères d’inéligibilité', champs_admin_procedure_path(@procedure), class: 'fr-link fr-icon-arrow-right-line fr-link--icon-right'
|
= link_to 'Ajouter un champ supportant les conditions d’inéligibilité', champs_admin_procedure_path(@procedure), class: 'fr-link fr-icon-arrow-right-line fr-link--icon-right'
|
||||||
= render Procedure::FixedFooterComponent.new(procedure: @procedure)
|
= render Procedure::FixedFooterComponent.new(procedure: @procedure)
|
||||||
- else
|
- else
|
||||||
= render Conditions::IneligibiliteRulesComponent.new(draft_revision: @procedure.draft_revision)
|
= render Conditions::IneligibiliteRulesComponent.new(draft_revision: @procedure.draft_revision)
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
= render partial: 'shared/dossiers/update_champs', locals: { to_show: @to_show, to_hide: @to_hide, to_update: @to_update, dossier: @dossier }
|
= render partial: 'shared/dossiers/update_champs', locals: { to_show: @to_show, to_hide: @to_hide, to_update: @to_update, dossier: @dossier }
|
||||||
|
|
||||||
- if !params.key?(:validate)
|
- if !params.key?(:validate)
|
||||||
- if @ineligibilite_rules_is_computable
|
- if @can_passer_en_construction_was && !@can_passer_en_construction_is
|
||||||
= turbo_stream.remove(dom_id(@dossier, :ineligibilite_rules_broken))
|
|
||||||
|
|
||||||
- if (@ineligibilite_rules_computable_changed && !@can_passer_en_construction_is) || (@can_passer_en_construction_was && !@can_passer_en_construction_is)
|
|
||||||
= turbo_stream.append('contenu', render(Dossiers::InvalidIneligibiliteRulesComponent.new(dossier: @dossier)))
|
= turbo_stream.append('contenu', render(Dossiers::InvalidIneligibiliteRulesComponent.new(dossier: @dossier)))
|
||||||
|
- else @ineligibilite_rules_is_computable
|
||||||
|
= turbo_stream.remove(dom_id(@dossier, :ineligibilite_rules_broken))
|
||||||
|
|
|
@ -610,7 +610,7 @@ fr:
|
||||||
otp_attempt: 'Code OTP (uniquement si vous avez déjà activé 2FA)'
|
otp_attempt: 'Code OTP (uniquement si vous avez déjà activé 2FA)'
|
||||||
procedure:
|
procedure:
|
||||||
zone: La démarche est mise en œuvre par
|
zone: La démarche est mise en œuvre par
|
||||||
ineligibilite_rules: "Les règles d’Inéligibilité"
|
ineligibilite_rules: "Les règles d’inéligibilité"
|
||||||
champs:
|
champs:
|
||||||
value: Valeur du champ
|
value: Valeur du champ
|
||||||
default_mail_attributes: &default_mail_attributes
|
default_mail_attributes: &default_mail_attributes
|
||||||
|
|
|
@ -8,7 +8,7 @@ fr:
|
||||||
procedure:
|
procedure:
|
||||||
hints:
|
hints:
|
||||||
description: Décrivez en quelques lignes le contexte, la finalité, etc.
|
description: Décrivez en quelques lignes le contexte, la finalité, etc.
|
||||||
description_target_audience: Décrivez en quelques lignes les destinataires finaux de la démarche, les critères d’éligibilité s’il y en a, les pré-requis, etc.
|
description_target_audience: Décrivez en quelques lignes les destinataires finaux de la démarche, les conditions d’éligibilité s’il y en a, les pré-requis, etc.
|
||||||
description_pj: Décrivez la liste des pièces jointes à fournir s’il y en a
|
description_pj: Décrivez la liste des pièces jointes à fournir s’il y en a
|
||||||
lien_site_web: "Il s'agit de la page de votre site web où le lien sera diffusé. Ex: https://exemple.gouv.fr/page_informant_sur_ma_demarche"
|
lien_site_web: "Il s'agit de la page de votre site web où le lien sera diffusé. Ex: https://exemple.gouv.fr/page_informant_sur_ma_demarche"
|
||||||
cadre_juridique: "Exemple: 'https://www.legifrance.gouv.fr/'"
|
cadre_juridique: "Exemple: 'https://www.legifrance.gouv.fr/'"
|
||||||
|
|
7
config/locales/models/procedure_revision/fr.yml
Normal file
7
config/locales/models/procedure_revision/fr.yml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
fr:
|
||||||
|
activerecord:
|
||||||
|
attributes:
|
||||||
|
procedure_revision:
|
||||||
|
ineligibilite_message: Message d’inéligibilité
|
||||||
|
hints:
|
||||||
|
ineligibilite_message: "Ce message sera affiché à l’usager si son dossier est bloqué et lui expliquera la raison de son inéligibilité."
|
|
@ -10,14 +10,14 @@ RSpec.describe Dossiers::EditFooterComponent, type: :component do
|
||||||
let(:dossier) { create(:dossier, :brouillon) }
|
let(:dossier) { create(:dossier, :brouillon) }
|
||||||
|
|
||||||
context 'when dossier can be submitted' do
|
context 'when dossier can be submitted' do
|
||||||
before { allow(component).to receive(:ineligibilite_rules_invalid?).and_return(false) }
|
before { allow(component).to receive(:can_passer_en_construction?).and_return(true) }
|
||||||
it 'renders submit button without disabled' do
|
it 'renders submit button without disabled' do
|
||||||
expect(subject).to have_selector('button', text: 'Déposer le dossier')
|
expect(subject).to have_selector('button', text: 'Déposer le dossier')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when dossier can not be submitted' do
|
context 'when dossier can not be submitted' do
|
||||||
before { allow(component).to receive(:ineligibilite_rules_invalid?).and_return(true) }
|
before { allow(component).to receive(:can_passer_en_construction?).and_return(false) }
|
||||||
it 'renders submit button with disabled' do
|
it 'renders submit button with disabled' do
|
||||||
expect(subject).to have_selector('a', text: 'Pourquoi je ne peux pas déposer mon dossier ?')
|
expect(subject).to have_selector('a', text: 'Pourquoi je ne peux pas déposer mon dossier ?')
|
||||||
expect(subject).to have_selector('button[disabled]', text: 'Déposer le dossier')
|
expect(subject).to have_selector('button[disabled]', text: 'Déposer le dossier')
|
||||||
|
@ -31,7 +31,7 @@ RSpec.describe Dossiers::EditFooterComponent, type: :component do
|
||||||
before { allow(dossier).to receive(:forked_with_changes?).and_return(true) }
|
before { allow(dossier).to receive(:forked_with_changes?).and_return(true) }
|
||||||
|
|
||||||
context 'when dossier can be submitted' do
|
context 'when dossier can be submitted' do
|
||||||
before { allow(component).to receive(:ineligibilite_rules_invalid?).and_return(false) }
|
before { allow(component).to receive(:can_passer_en_construction?).and_return(true) }
|
||||||
|
|
||||||
it 'renders submit button without disabled' do
|
it 'renders submit button without disabled' do
|
||||||
expect(subject).to have_selector('button', text: 'Déposer les modifications')
|
expect(subject).to have_selector('button', text: 'Déposer les modifications')
|
||||||
|
@ -39,7 +39,7 @@ RSpec.describe Dossiers::EditFooterComponent, type: :component do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when dossier can not be submitted' do
|
context 'when dossier can not be submitted' do
|
||||||
before { allow(component).to receive(:ineligibilite_rules_invalid?).and_return(true) }
|
before { allow(component).to receive(:can_passer_en_construction?).and_return(false) }
|
||||||
|
|
||||||
it 'renders submit button with disabled' do
|
it 'renders submit button with disabled' do
|
||||||
expect(subject).to have_selector('a', text: 'Pourquoi je ne peux pas déposer mon dossier ?')
|
expect(subject).to have_selector('a', text: 'Pourquoi je ne peux pas déposer mon dossier ?')
|
||||||
|
|
|
@ -19,7 +19,7 @@ describe TypesDeChampEditor::EditorComponent, type: :component do
|
||||||
context 'types_de_champ_private' do
|
context 'types_de_champ_private' do
|
||||||
let(:is_annotation) { true }
|
let(:is_annotation) { true }
|
||||||
it 'does not render public champs errors' do
|
it 'does not render public champs errors' do
|
||||||
expect(subject).to have_selector("a", "private")
|
expect(subject).to have_selector("a", text: "private")
|
||||||
expect(subject).to have_text("doit comporter au moins un choix sélectionnable")
|
expect(subject).to have_text("doit comporter au moins un choix sélectionnable")
|
||||||
expect(subject).not_to have_text("public")
|
expect(subject).not_to have_text("public")
|
||||||
end
|
end
|
||||||
|
|
|
@ -197,14 +197,14 @@ describe Administrateurs::IneligibiliteRulesController, type: :controller do
|
||||||
let(:types_de_champ_public) { [] }
|
let(:types_de_champ_public) { [] }
|
||||||
render_views
|
render_views
|
||||||
|
|
||||||
it { expect(response.body).to have_link("Ajouter un champ supportant les critères d’inéligibilité") }
|
it { expect(response.body).to have_link("Ajouter un champ supportant les conditions d’inéligibilité") }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'rendered with tdc' do
|
context 'rendered with tdc' do
|
||||||
let(:types_de_champ_public) { [{ type: :yes_no }] }
|
let(:types_de_champ_public) { [{ type: :yes_no }] }
|
||||||
render_views
|
render_views
|
||||||
|
|
||||||
it { expect(response.body).not_to have_link("Ajouter un champ supportant les critères d’inéligibilité") }
|
it { expect(response.body).not_to have_link("Ajouter un champ supportant les conditions d’inéligibilité") }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -791,26 +791,27 @@ describe Users::DossiersController, type: :controller do
|
||||||
end
|
end
|
||||||
render_views
|
render_views
|
||||||
|
|
||||||
context 'when it pass from undefined to true' do
|
context 'when it switches from true to false' do
|
||||||
let(:value) { must_be_greater_than + 1 }
|
let(:value) { must_be_greater_than + 1 }
|
||||||
|
|
||||||
it 'raises popup' do
|
it 'raises popup' do
|
||||||
subject
|
subject
|
||||||
dossier.reload
|
dossier.reload
|
||||||
expect(dossier.can_passer_en_construction?).to be_falsey
|
expect(dossier.can_passer_en_construction?).to be_falsey
|
||||||
expect(assigns(:ineligibilite_rules_was_computable)).to eq(false)
|
expect(assigns(:can_passer_en_construction_was)).to eq(true)
|
||||||
expect(assigns(:ineligibilite_rules_is_computable)).to eq(true)
|
expect(assigns(:can_passer_en_construction_is)).to eq(false)
|
||||||
expect(response.body).to match(ActionView::RecordIdentifier.dom_id(dossier, :ineligibilite_rules_broken))
|
expect(response.body).to match(ActionView::RecordIdentifier.dom_id(dossier, :ineligibilite_rules_broken))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
context 'when it pass from undefined to false' do
|
|
||||||
|
context 'when it stays true' do
|
||||||
let(:value) { must_be_greater_than - 1 }
|
let(:value) { must_be_greater_than - 1 }
|
||||||
it 'does nothing' do
|
it 'does nothing' do
|
||||||
subject
|
subject
|
||||||
dossier.reload
|
dossier.reload
|
||||||
expect(dossier.can_passer_en_construction?).to be_truthy
|
expect(dossier.can_passer_en_construction?).to be_truthy
|
||||||
expect(assigns(:ineligibilite_rules_was_computable)).to eq(false)
|
expect(assigns(:can_passer_en_construction_was)).to eq(true)
|
||||||
expect(assigns(:ineligibilite_rules_is_computable)).to eq(true)
|
expect(assigns(:can_passer_en_construction_is)).to eq(true)
|
||||||
expect(response.body).not_to have_selector("##{ActionView::RecordIdentifier.dom_id(dossier, :ineligibilite_rules_broken)}")
|
expect(response.body).not_to have_selector("##{ActionView::RecordIdentifier.dom_id(dossier, :ineligibilite_rules_broken)}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,42 +6,6 @@ describe Logic::And do
|
||||||
it { expect(and_from([true, true, false]).compute).to be false }
|
it { expect(and_from([true, true, false]).compute).to be false }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#computable?' do
|
|
||||||
let(:champ_1) { create(:champ_integer_number, value: value_1) }
|
|
||||||
let(:champ_2) { create(:champ_integer_number, value: value_2) }
|
|
||||||
|
|
||||||
let(:logic) do
|
|
||||||
ds_and([
|
|
||||||
greater_than(champ_value(champ_1.stable_id), constant(1)),
|
|
||||||
less_than(champ_value(champ_2.stable_id), constant(10))
|
|
||||||
])
|
|
||||||
end
|
|
||||||
|
|
||||||
subject { logic.computable?([champ_1, champ_2]) }
|
|
||||||
|
|
||||||
context "when none of champs.value are filled, and logic can't be computed" do
|
|
||||||
let(:value_1) { nil }
|
|
||||||
let(:value_2) { nil }
|
|
||||||
it { is_expected.to be_falsey }
|
|
||||||
end
|
|
||||||
context "when one champs has a value (that compute to false) the other has not, and logic keeps waiting for the 2nd value" do
|
|
||||||
let(:value_1) { 1 }
|
|
||||||
let(:value_2) { nil }
|
|
||||||
it { is_expected.to be_falsey }
|
|
||||||
end
|
|
||||||
context 'when all champs.value are filled, and logic can be computed' do
|
|
||||||
let(:value_1) { 1 }
|
|
||||||
let(:value_2) { 10 }
|
|
||||||
it { is_expected.to be_truthy }
|
|
||||||
end
|
|
||||||
context 'when one champs is not visible and the other has a value, and logic can be computed' do
|
|
||||||
let(:value_1) { 1 }
|
|
||||||
let(:value_2) { nil }
|
|
||||||
before { expect(champ_2).to receive(:visible?).and_return(false) }
|
|
||||||
it { is_expected.to be_truthy }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#to_s' do
|
describe '#to_s' do
|
||||||
it do
|
it do
|
||||||
expect(and_from([true, false, true]).to_s([])).to eq "(Oui && Non && Oui)"
|
expect(and_from([true, false, true]).to_s([])).to eq "(Oui && Non && Oui)"
|
||||||
|
|
|
@ -28,19 +28,6 @@ describe Logic::BinaryOperator do
|
||||||
it { expect(greater_than(constant(2), champ_value(champ.stable_id)).sources).to eq([champ.stable_id]) }
|
it { expect(greater_than(constant(2), champ_value(champ.stable_id)).sources).to eq([champ.stable_id]) }
|
||||||
it { expect(greater_than(champ_value(champ.stable_id), champ_value(champ2.stable_id)).sources).to eq([champ.stable_id, champ2.stable_id]) }
|
it { expect(greater_than(champ_value(champ.stable_id), champ_value(champ2.stable_id)).sources).to eq([champ.stable_id, champ2.stable_id]) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#computable?' do
|
|
||||||
let(:champ) { create(:champ_integer_number, value: nil) }
|
|
||||||
|
|
||||||
it 'computable?' do
|
|
||||||
expect(greater_than(champ_value(champ.stable_id), constant(1)).computable?([])).to be(false)
|
|
||||||
expect(greater_than(champ_value(champ.stable_id), constant(1)).computable?([champ])).to be(false)
|
|
||||||
allow(champ).to receive(:value).and_return(double(present?: true))
|
|
||||||
expect(greater_than(champ_value(champ.stable_id), constant(1)).computable?([champ])).to be(true)
|
|
||||||
allow(champ).to receive(:visible?).and_return(false)
|
|
||||||
expect(greater_than(champ_value(champ.stable_id), constant(1)).computable?([champ])).to be(false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Logic::GreaterThan do
|
describe Logic::GreaterThan do
|
||||||
|
|
|
@ -7,49 +7,6 @@ describe Logic::Or do
|
||||||
it { expect(or_from([false, false, false]).compute).to be false }
|
it { expect(or_from([false, false, false]).compute).to be false }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#computable?' do
|
|
||||||
let(:champ_1) { create(:champ_integer_number, value: value_1) }
|
|
||||||
let(:champ_2) { create(:champ_integer_number, value: value_2) }
|
|
||||||
|
|
||||||
let(:logic) do
|
|
||||||
ds_or([
|
|
||||||
greater_than(champ_value(champ_1.stable_id), constant(1)),
|
|
||||||
less_than(champ_value(champ_2.stable_id), constant(10))
|
|
||||||
])
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with all champs' do
|
|
||||||
subject { logic.computable?([champ_1, champ_2]) }
|
|
||||||
|
|
||||||
context "when none of champs.value are filled, or logic can't be computed" do
|
|
||||||
let(:value_1) { nil }
|
|
||||||
let(:value_2) { nil }
|
|
||||||
it { is_expected.to be_falsey }
|
|
||||||
end
|
|
||||||
context "when one champs has a value (that compute to false) the other has not, or logic keeps waiting for the 2nd value" do
|
|
||||||
let(:value_1) { 1 }
|
|
||||||
let(:value_2) { nil }
|
|
||||||
it { is_expected.to be_falsey }
|
|
||||||
end
|
|
||||||
context 'when all champs.value are filled, or logic can be computed' do
|
|
||||||
let(:value_1) { 1 }
|
|
||||||
let(:value_2) { 10 }
|
|
||||||
it { is_expected.to be_truthy }
|
|
||||||
end
|
|
||||||
context 'when one champs.value and his condition is true, or logic can be computed' do
|
|
||||||
let(:value_1) { 2 }
|
|
||||||
let(:value_2) { nil }
|
|
||||||
it { is_expected.to be_truthy }
|
|
||||||
end
|
|
||||||
context 'when one champs is not visible and the other has a value that fails, or logic can be computed' do
|
|
||||||
let(:value_1) { 1 }
|
|
||||||
let(:value_2) { nil }
|
|
||||||
before { expect(champ_2).to receive(:visible?).and_return(false) }
|
|
||||||
it { is_expected.to be_truthy }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#to_s' do
|
describe '#to_s' do
|
||||||
it { expect(or_from([true, false, true]).to_s).to eq "(Oui || Non || Oui)" }
|
it { expect(or_from([true, false, true]).to_s).to eq "(Oui || Non || Oui)" }
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,13 +9,13 @@ describe 'Administrateurs can edit procedures', js: true do
|
||||||
scenario 'setup eligibilite' do
|
scenario 'setup eligibilite' do
|
||||||
# explain no champ compatible
|
# explain no champ compatible
|
||||||
visit admin_procedure_path(procedure)
|
visit admin_procedure_path(procedure)
|
||||||
expect(page).to have_content("Champs à configurer")
|
expect(page).to have_content("Désactivé")
|
||||||
|
|
||||||
# explain which champs are compatible
|
# explain which champs are compatible
|
||||||
visit edit_admin_procedure_ineligibilite_rules_path(procedure)
|
visit edit_admin_procedure_ineligibilite_rules_path(procedure)
|
||||||
expect(page).to have_content("Inéligibilité des dossiers")
|
expect(page).to have_content("Inéligibilité des dossiers")
|
||||||
expect(page).to have_content("Pour configurer l’inéligibilité des dossiers, votre formulaire doit comporter au moins un champ supportant les critères d’inéligibilité. Il vous faut donc ajouter au moins un des champs suivant à votre formulaire : ")
|
expect(page).to have_content("Pour configurer l’inéligibilité des dossiers, votre formulaire doit comporter au moins un champ supportant les conditions d’inéligibilité. Il vous faut donc ajouter au moins un des champs suivant à votre formulaire : ")
|
||||||
click_on "Ajouter un champ supportant les critères d’inéligibilité"
|
click_on "Ajouter un champ supportant les conditions d’inéligibilité"
|
||||||
|
|
||||||
# setup a compatible champ
|
# setup a compatible champ
|
||||||
expect(page).to have_content('Champs du formulaire')
|
expect(page).to have_content('Champs du formulaire')
|
||||||
|
@ -32,7 +32,7 @@ describe 'Administrateurs can edit procedures', js: true do
|
||||||
# setup rules and stuffs
|
# setup rules and stuffs
|
||||||
expect(page).to have_content("Inéligibilité des dossiers")
|
expect(page).to have_content("Inéligibilité des dossiers")
|
||||||
fill_in "Message d’inéligibilité", with: "vous n'etes pas eligible"
|
fill_in "Message d’inéligibilité", with: "vous n'etes pas eligible"
|
||||||
find('label', text: 'Inéligibilité des dossiers').click
|
find('label', text: 'Bloquer le dépôt des dossiers répondant à des conditions d’inéligibilité').click
|
||||||
click_on "Ajouter une règle d’inéligibilité"
|
click_on "Ajouter une règle d’inéligibilité"
|
||||||
all('select').first.select 'Un champ oui non'
|
all('select').first.select 'Un champ oui non'
|
||||||
click_on 'Enregistrer'
|
click_on 'Enregistrer'
|
||||||
|
|
|
@ -9,7 +9,7 @@ describe 'Dossier Inéligibilité', js: true do
|
||||||
|
|
||||||
let(:published_revision) { procedure.published_revision }
|
let(:published_revision) { procedure.published_revision }
|
||||||
let(:first_tdc) { published_revision.types_de_champ.first }
|
let(:first_tdc) { published_revision.types_de_champ.first }
|
||||||
let(:second_tdc) { published_revision.types_de_champ.last }
|
let(:second_tdc) { published_revision.types_de_champ.second }
|
||||||
let(:ineligibilite_message) { 'sry vous pouvez aps soumettre votre dossier' }
|
let(:ineligibilite_message) { 'sry vous pouvez aps soumettre votre dossier' }
|
||||||
let(:eligibilite_params) { { ineligibilite_enabled: true, ineligibilite_message: } }
|
let(:eligibilite_params) { { ineligibilite_enabled: true, ineligibilite_message: } }
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@ describe 'Dossier Inéligibilité', js: true do
|
||||||
login_as user, scope: :user
|
login_as user, scope: :user
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'single condition' do
|
describe 'ineligibilite_rules with a single BinaryOperator' do
|
||||||
let(:types_de_champ_public) { [{ type: :yes_no }] }
|
let(:types_de_champ_public) { [{ type: :yes_no, stable_id: 1 }] }
|
||||||
let(:ineligibilite_rules) { ds_eq(champ_value(first_tdc.stable_id), constant(true)) }
|
let(:ineligibilite_rules) { ds_eq(champ_value(first_tdc.stable_id), constant(true)) }
|
||||||
|
|
||||||
scenario 'can submit, can not submit, reload' do
|
scenario 'can submit, can not submit, reload' do
|
||||||
|
@ -28,24 +28,33 @@ describe 'Dossier Inéligibilité', js: true do
|
||||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
||||||
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")
|
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||||
|
|
||||||
# does raise error when dossier is filled with valid condition
|
# does raise error when dossier is filled with condition that does not match
|
||||||
find("label", text: "Non").click
|
within "#champ-1" do
|
||||||
|
find("label", text: "Non").click
|
||||||
|
end
|
||||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
||||||
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")
|
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||||
|
|
||||||
# raise error when dossier is filled with invalid condition
|
# raise error when dossier is filled with condition that matches
|
||||||
find("label", text: "Oui").click
|
within "#champ-1" do
|
||||||
|
find("label", text: "Oui").click
|
||||||
|
end
|
||||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: true)
|
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: true)
|
||||||
expect(page).to have_content("Vous ne pouvez pas déposer votre dossier")
|
expect(page).to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||||
|
|
||||||
# reload page and see error because it was filled
|
# reload page and see error
|
||||||
visit brouillon_dossier_path(dossier)
|
visit brouillon_dossier_path(dossier)
|
||||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: true)
|
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: true)
|
||||||
expect(page).to have_content("Vous ne pouvez pas déposer votre dossier")
|
expect(page).to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||||
|
|
||||||
# modal is closable, and we can change our dossier response to be eligible
|
# modal is closable, and we can change our dossier response to be eligible
|
||||||
|
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: true)
|
||||||
within("#modal-eligibilite-rules-dialog") { click_on "Fermer" }
|
within("#modal-eligibilite-rules-dialog") { click_on "Fermer" }
|
||||||
find("label", text: "Non").click
|
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
|
||||||
|
|
||||||
|
within "#champ-1" do
|
||||||
|
find("label", text: "Non").click
|
||||||
|
end
|
||||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
||||||
|
|
||||||
# it works, yay
|
# it works, yay
|
||||||
|
@ -54,7 +63,7 @@ describe 'Dossier Inéligibilité', js: true do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'or condition' do
|
describe 'ineligibilite_rules with a Or' do
|
||||||
let(:types_de_champ_public) { [{ type: :yes_no, libelle: 'l1' }, { type: :drop_down_list, libelle: 'l2', options: ['Paris', 'Marseille'] }] }
|
let(:types_de_champ_public) { [{ type: :yes_no, libelle: 'l1' }, { type: :drop_down_list, libelle: 'l2', options: ['Paris', 'Marseille'] }] }
|
||||||
let(:ineligibilite_rules) do
|
let(:ineligibilite_rules) do
|
||||||
ds_or([
|
ds_or([
|
||||||
|
@ -69,15 +78,17 @@ describe 'Dossier Inéligibilité', js: true do
|
||||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
||||||
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")
|
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||||
|
|
||||||
# only one condition is matches, cannot submit dossier and error message is clear
|
# first condition matches (so ineligible), cannot submit dossier and error message is clear
|
||||||
within "#champ-#{first_tdc.stable_id}" do
|
within "#champ-#{first_tdc.stable_id}" do
|
||||||
find("label", text: "Oui").click
|
find("label", text: "Oui").click
|
||||||
end
|
end
|
||||||
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: true)
|
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: true)
|
||||||
expect(page).to have_content("Vous ne pouvez pas déposer votre dossier")
|
expect(page).to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||||
|
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: true)
|
||||||
within("#modal-eligibilite-rules-dialog") { click_on "Fermer" }
|
within("#modal-eligibilite-rules-dialog") { click_on "Fermer" }
|
||||||
|
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
|
||||||
|
|
||||||
# only one condition does not matches, I can conitnue
|
# first condition does not matches, I can conitnue
|
||||||
within "#champ-#{first_tdc.stable_id}" do
|
within "#champ-#{first_tdc.stable_id}" do
|
||||||
find("label", text: "Non").click
|
find("label", text: "Non").click
|
||||||
end
|
end
|
||||||
|
@ -88,12 +99,15 @@ describe 'Dossier Inéligibilité', js: true do
|
||||||
click_on "Accéder à votre dossier"
|
click_on "Accéder à votre dossier"
|
||||||
click_on "Modifier le dossier"
|
click_on "Modifier le dossier"
|
||||||
|
|
||||||
# one condition matches, means i'm blocked to send my file.
|
# first matches, means i'm blocked to send my file.
|
||||||
within "#champ-#{first_tdc.stable_id}" do
|
within "#champ-#{first_tdc.stable_id}" do
|
||||||
find("label", text: "Oui").click
|
find("label", text: "Oui").click
|
||||||
end
|
end
|
||||||
expect(page).to have_selector(:button, text: "Déposer les modifications", disabled: true)
|
expect(page).to have_selector(:button, text: "Déposer les modifications", disabled: true)
|
||||||
|
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: true)
|
||||||
within("#modal-eligibilite-rules-dialog") { click_on "Fermer" }
|
within("#modal-eligibilite-rules-dialog") { click_on "Fermer" }
|
||||||
|
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
|
||||||
|
|
||||||
within "#champ-#{first_tdc.stable_id}" do
|
within "#champ-#{first_tdc.stable_id}" do
|
||||||
find("label", text: "Non").click
|
find("label", text: "Non").click
|
||||||
end
|
end
|
||||||
|
@ -104,7 +118,56 @@ describe 'Dossier Inéligibilité', js: true do
|
||||||
find("label", text: 'Paris').click
|
find("label", text: 'Paris').click
|
||||||
end
|
end
|
||||||
expect(page).to have_selector(:button, text: "Déposer les modifications", disabled: true)
|
expect(page).to have_selector(:button, text: "Déposer les modifications", disabled: true)
|
||||||
|
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: true)
|
||||||
within("#modal-eligibilite-rules-dialog") { click_on "Fermer" }
|
within("#modal-eligibilite-rules-dialog") { click_on "Fermer" }
|
||||||
|
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
|
||||||
|
|
||||||
|
# none of conditions matches, i can submit
|
||||||
|
within "#champ-#{second_tdc.stable_id}" do
|
||||||
|
find("label", text: 'Marseille').click
|
||||||
|
end
|
||||||
|
|
||||||
|
# it works, yay
|
||||||
|
click_on "Déposer les modifications"
|
||||||
|
wait_until { dossier.reload.en_construction? == true }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'ineligibilite_rules with a And and all visible champs' do
|
||||||
|
let(:types_de_champ_public) { [{ type: :yes_no, libelle: 'l1' }, { type: :drop_down_list, libelle: 'l2', options: ['Paris', 'Marseille'] }] }
|
||||||
|
let(:ineligibilite_rules) do
|
||||||
|
ds_and([
|
||||||
|
ds_eq(champ_value(first_tdc.stable_id), constant(true)),
|
||||||
|
ds_eq(champ_value(second_tdc.stable_id), constant('Paris'))
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'can submit, can not submit, can edit, etc...' do
|
||||||
|
visit brouillon_dossier_path(dossier)
|
||||||
|
# no error while dossier is empty
|
||||||
|
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
||||||
|
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||||
|
|
||||||
|
# only one condition is matches, can submit dossier
|
||||||
|
within "#champ-#{first_tdc.stable_id}" do
|
||||||
|
find("label", text: "Oui").click
|
||||||
|
end
|
||||||
|
expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false)
|
||||||
|
expect(page).not_to have_content("Vous ne pouvez pas déposer votre dossier")
|
||||||
|
|
||||||
|
# Now test dossier modification
|
||||||
|
click_on "Déposer le dossier"
|
||||||
|
click_on "Accéder à votre dossier"
|
||||||
|
click_on "Modifier le dossier"
|
||||||
|
|
||||||
|
# second condition matches, means i'm blocked to send my file
|
||||||
|
within "#champ-#{second_tdc.stable_id}" do
|
||||||
|
find("label", text: 'Paris').click
|
||||||
|
end
|
||||||
|
expect(page).to have_selector(:button, text: "Déposer les modifications", disabled: true)
|
||||||
|
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: true)
|
||||||
|
within("#modal-eligibilite-rules-dialog") { click_on "Fermer" }
|
||||||
|
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
|
||||||
|
|
||||||
# none of conditions matches, i can submit
|
# none of conditions matches, i can submit
|
||||||
within "#champ-#{second_tdc.stable_id}" do
|
within "#champ-#{second_tdc.stable_id}" do
|
||||||
|
|
|
@ -155,7 +155,6 @@ describe 'shared/dossiers/edit', type: :view do
|
||||||
let(:dossier) { create(:dossier, procedure:) }
|
let(:dossier) { create(:dossier, procedure:) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow_any_instance_of(Dossiers::InvalidIneligibiliteRulesComponent).to receive(:ineligibilite_rules_computable?).and_return(true)
|
|
||||||
allow(dossier).to receive(:can_passer_en_construction?).and_return(false)
|
allow(dossier).to receive(:can_passer_en_construction?).and_return(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue