From c480bc00c381f4b1c108b862e028bd9e03fd40ba Mon Sep 17 00:00:00 2001 From: mfo Date: Wed, 5 Jun 2024 17:40:35 +0200 Subject: [PATCH] feat(Users/Dossiers#submit_brouillon_or_en_construction): prevent transition to en_construction if ineligibilite_rules matches. pop error nicely --- app/controllers/users/dossiers_controller.rb | 20 +-- app/models/dossier.rb | 2 +- .../users/dossier_ineligibilite_spec.rb | 119 ++++++++++++++++++ 3 files changed, 126 insertions(+), 15 deletions(-) create mode 100644 spec/system/users/dossier_ineligibilite_spec.rb diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index e686683ff..ebfa2cdb4 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -231,9 +231,9 @@ module Users def submit_brouillon @dossier = dossier_with_champs(pj_template: false) - @errors = submit_dossier_and_compute_errors + submit_dossier_and_compute_errors - if @errors.blank? + if @dossier.errors.blank? && @dossier.can_passer_en_construction? @dossier.passer_en_construction! @dossier.process_declarative! @dossier.process_sva_svr! @@ -278,9 +278,9 @@ module Users editing_fork_origin.resolve_pending_correction end - @errors = submit_dossier_and_compute_errors + submit_dossier_and_compute_errors - if @errors.blank? + if @dossier.errors.blank? && @dossier.can_passer_en_construction? editing_fork_origin.merge_fork(@dossier) editing_fork_origin.submit_en_construction! @@ -288,7 +288,6 @@ module Users else respond_to do |format| format.html do - @dossier = editing_fork_origin render :modifier end @@ -570,21 +569,14 @@ module Users def submit_dossier_and_compute_errors @dossier.validate(:champs_public_value) - - errors = @dossier.errors - @dossier.check_mandatory_and_visible_champs.each do |error_on_champ| - errors.import(error_on_champ) - end + @dossier.check_mandatory_and_visible_champs if @dossier.editing_fork_origin&.pending_correction? @dossier.editing_fork_origin.validate(:champs_public_value) @dossier.editing_fork_origin.errors.where(:pending_correction).each do |error| - errors.import(error) + @dossier.errors.import(error) end - end - - errors end def ensure_ownership! diff --git a/app/models/dossier.rb b/app/models/dossier.rb index e83edfb97..7a1c611a8 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -940,7 +940,7 @@ class Dossier < ApplicationRecord .filter(&:visible?) .filter(&:mandatory_blank?) .map do |champ| - champ.errors.add(:value, :missing) + errors.import(champ.errors.add(:value, :missing)) end end diff --git a/spec/system/users/dossier_ineligibilite_spec.rb b/spec/system/users/dossier_ineligibilite_spec.rb new file mode 100644 index 000000000..366dac780 --- /dev/null +++ b/spec/system/users/dossier_ineligibilite_spec.rb @@ -0,0 +1,119 @@ +require 'system/users/dossier_shared_examples.rb' + +describe 'Dossier Inéligibilité', js: true do + include Logic + + let(:user) { create(:user) } + let(:procedure) { create(:procedure, :published, types_de_champ_public:) } + let(:dossier) { create(:dossier, procedure:, user:) } + + let(:published_revision) { procedure.published_revision } + let(:first_tdc) { published_revision.types_de_champ.first } + let(:second_tdc) { published_revision.types_de_champ.last } + let(:ineligibilite_message) { 'sry vous pouvez aps soumettre votre dossier' } + let(:eligibilite_params) { { ineligibilite_enabled: true, ineligibilite_message: } } + + before do + published_revision.update(eligibilite_params.merge(ineligibilite_rules:)) + login_as user, scope: :user + end + + context 'single condition' do + let(:types_de_champ_public) { [{ type: :yes_no }] } + let(:ineligibilite_rules) { ds_eq(champ_value(first_tdc.stable_id), constant(true)) } + + scenario 'can submit, can not submit, reload' 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") + + # does raise error when dossier is filled with valid condition + find("label", text: "Non").click + 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") + + # raise error when dossier is filled with invalid condition + find("label", text: "Oui").click + 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") + + # reload page and see error because it was filled + visit brouillon_dossier_path(dossier) + 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") + + # modal is closable, and we can change our dossier response to be eligible + within("#modal-eligibilite-rules-dialog") { click_on "Fermer" } + find("label", text: "Non").click + expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false) + + # it works, yay + click_on "Déposer le dossier" + wait_until { dossier.reload.en_construction? == true } + end + end + + context 'or condition' 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_or([ + 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, cannot submit dossier and error message is clear + 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: true) + expect(page).to have_content("Vous ne pouvez pas déposer votre dossier") + within("#modal-eligibilite-rules-dialog") { click_on "Fermer" } + + # only one condition does not matches, I can conitnue + within "#champ-#{first_tdc.stable_id}" do + find("label", text: "Non").click + end + expect(page).to have_selector(:button, text: "Déposer le dossier", disabled: false) + + # Now test dossier modification + click_on "Déposer le dossier" + click_on "Accéder à votre dossier" + click_on "Modifier le dossier" + + # one condition matches, means i'm blocked to send my file. + within "#champ-#{first_tdc.stable_id}" do + find("label", text: "Oui").click + end + expect(page).to have_selector(:button, text: "Déposer les modifications", disabled: true) + within("#modal-eligibilite-rules-dialog") { click_on "Fermer" } + within "#champ-#{first_tdc.stable_id}" do + find("label", text: "Non").click + end + expect(page).to have_selector(:button, text: "Déposer les modifications", disabled: false) + + # 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) + within("#modal-eligibilite-rules-dialog") { click_on "Fermer" } + + # 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 +end