fix(dossier): show ineligibilite message on update

This commit is contained in:
Colin Darie 2024-12-10 19:13:01 +01:00
parent eb682f1e64
commit 009e426c31
No known key found for this signature in database
GPG key ID: 4FB865FDBCA4BCC4
9 changed files with 55 additions and 63 deletions

View file

@ -1,18 +1,28 @@
# frozen_string_literal: true
class Dossiers::InvalidIneligibiliteRulesComponent < ApplicationComponent
delegate :can_passer_en_construction?, to: :@dossier
delegate :can_passer_en_construction?, to: :dossier
def initialize(dossier:)
def initialize(dossier:, wrapped: true)
@dossier = dossier
@revision = dossier.revision
@opened = !dossier.can_passer_en_construction?
@wrapped = wrapped
end
private
attr_reader :dossier
def render?
!can_passer_en_construction?
dossier.revision.ineligibilite_enabled?
end
def error_message
@dossier.revision.ineligibilite_message
dossier.revision.ineligibilite_message
end
def opened? = @opened
def wrapped? = @wrapped
end

View file

@ -1,8 +1,8 @@
%div{ id: dom_id(@dossier, :ineligibilite_rules_broken), data: { controller: 'ineligibilite-rules-match', turbo_force: :server } }
%button.fr-sr-only{ aria: {controls: 'modal-eligibilite-rules-dialog' }, data: {'fr-opened': "false" } }
- modal_content = capture do
%button.fr-sr-only{ aria: { controls: 'modal-eligibilite-rules-dialog' }, data: { 'fr-opened': opened?.to_s } }
show modal
%dialog.fr-modal{ "aria-labelledby" => "fr-modal-title-modal-1", role: "dialog", id: 'modal-eligibilite-rules-dialog', data: { 'ineligibilite-rules-match-target' => 'dialog' } }
%dialog.fr-modal{ "aria-labelledby" => "fr-modal-title-modal-1", role: "dialog", id: 'modal-eligibilite-rules-dialog', data: { 'turbo-permanent' => true } }
.fr-container.fr-container--fluid.fr-container-md
.fr-grid-row.fr-grid-row--center
.fr-col-12.fr-col-md-8.fr-col-lg-6
@ -14,3 +14,9 @@
%span.fr-icon-arrow-right-line.fr-icon--lg>
= t('.modal.title')
%p= error_message
- if wrapped?
%div{ id: dom_id(@dossier, :ineligibilite_rules_broken) }
= modal_content
- else
= modal_content

View file

@ -280,9 +280,7 @@ module Users
def update
@dossier = dossier.en_construction? ? dossier.find_editing_fork(dossier.user) : dossier
@dossier = dossier_with_champs(pj_template: false)
@can_passer_en_construction_was, @can_passer_en_construction_is = dossier.track_can_passer_en_construction do
update_dossier_and_compute_errors
end
respond_to do |format|
format.turbo_stream do

View file

@ -1,19 +0,0 @@
import { ApplicationController } from './application_controller';
declare interface modal {
disclose: () => void;
}
declare interface dsfr {
modal: modal;
}
declare const window: Window &
typeof globalThis & { dsfr: (elem: HTMLElement) => dsfr };
export class InvalidIneligibiliteRulesController extends ApplicationController {
static targets = ['dialog'];
declare dialogTarget: HTMLElement;
connect() {
setTimeout(() => window.dsfr(this.dialogTarget).modal.disclose(), 100);
}
}

View file

@ -1025,18 +1025,6 @@ class Dossier < ApplicationRecord
procedure.accuse_lecture? && termine?
end
def track_can_passer_en_construction
if !revision.ineligibilite_enabled
yield
[true, true] # without eligibilite rules, we never reach dossier.champs.visible?, don't cache anything
else
from = can_passer_en_construction? # with eligibilite rules, self.champ[x].visible is cached by passing thru conditions checks
yield
champs.map(&:reset_visible) # we must reset self.champs[x].visible?, because an update occurred and we should re-evaluate champs[x] visibility
[from, can_passer_en_construction?]
end
end
private
def build_default_champs

View file

@ -1,10 +1,7 @@
= 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 @can_passer_en_construction_was && !@can_passer_en_construction_is
= turbo_stream.append('contenu', render(Dossiers::InvalidIneligibiliteRulesComponent.new(dossier: @dossier)))
- else @ineligibilite_rules_is_computable
= turbo_stream.remove(dom_id(@dossier, :ineligibilite_rules_broken))
- if params[:validate].present? && @dossier.revision.ineligibilite_enabled?
= turbo_stream.update dom_id(@dossier, :ineligibilite_rules_broken), render(Dossiers::InvalidIneligibiliteRulesComponent.new(dossier: @dossier, wrapped: false))
- if @update_contact_information
= turbo_stream.update "contact_information", partial: 'shared/dossiers/update_contact_information', locals: { dossier: @dossier, procedure: @dossier.procedure }

View file

@ -775,9 +775,11 @@ describe Users::DossiersController, type: :controller do
let(:types_de_champ_public) { [{ type: :text }, { type: :integer_number }] }
let(:text_champ) { dossier.project_champs_public.first }
let(:number_champ) { dossier.project_champs_public.last }
let(:validate) { "true" }
let(:submit_payload) do
{
id: dossier.id,
validate:,
dossier: {
groupe_instructeur_id: dossier.groupe_instructeur_id,
champs_public_attributes: {
@ -805,28 +807,36 @@ describe Users::DossiersController, type: :controller do
end
render_views
context 'when it switches from true to false' do
context 'when it becomes invalid' do
let(:value) { must_be_greater_than + 1 }
it 'raises popup' do
subject
dossier.reload
expect(dossier.can_passer_en_construction?).to be_falsey
expect(assigns(:can_passer_en_construction_was)).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(/aria-controls='modal-eligibilite-rules-dialog'[^>]*data-fr-opened='true'/)
end
end
context 'when it stays true' do
context 'when it says valid' do
let(:value) { must_be_greater_than - 1 }
it 'does nothing' do
subject
dossier.reload
expect(dossier.can_passer_en_construction?).to be_truthy
expect(assigns(:can_passer_en_construction_was)).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).to match(/aria-controls='modal-eligibilite-rules-dialog'[^>]*data-fr-opened='false'/)
end
end
context 'when not validating' do
let(:validate) { nil }
let(:value) { must_be_greater_than + 1 }
it 'does not render invalid ineligible modal' do
subject
dossier.reload
expect(dossier.can_passer_en_construction?).to be_falsey
expect(response.body).not_to include("aria-controls='modal-eligibilite-rules-dialog'")
end
end
end

View file

@ -28,21 +28,21 @@ describe 'Dossier Inéligibilité', js: true 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")
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
# does raise error when dossier is filled with condition that does not match
# does nothing when dossier is filled with condition that does not match
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).not_to have_content("Vous ne pouvez pas déposer votre dossier")
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
# raise error when dossier is filled with condition that matches
# open modal when dossier is filled with condition that matches
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_content("Vous ne pouvez pas déposer votre dossier")
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: true)
# reload page and see error
visit brouillon_dossier_path(dossier)
@ -51,6 +51,7 @@ describe 'Dossier Inéligibilité', js: true do
# modal is closable, and we can change our dossier response to be eligible
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: true)
expect(page).to have_text("Vous ne pouvez pas déposer votre dossier")
within("#modal-eligibilite-rules-dialog") { click_on "Fermer" }
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
@ -78,7 +79,7 @@ describe 'Dossier Inéligibilité', js: true 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")
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
# first condition matches (so ineligible), cannot submit dossier and error message is clear
within "#champ-#{first_tdc.stable_id}" do
@ -148,14 +149,14 @@ describe 'Dossier Inéligibilité', js: true 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")
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
# 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")
expect(page).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
# Now test dossier modification
click_on "Déposer le dossier"
@ -196,7 +197,7 @@ describe 'Dossier Inéligibilité', js: true do
scenario 'ineligibilite rules without validation on champ ensure to re-process cached champs.visible' do
visit brouillon_dossier_path(dossier)
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).to have_selector("#modal-eligibilite-rules-dialog", visible: false)
within "#champ-1" do
find("label", text: "Non").click

View file

@ -160,6 +160,7 @@ describe 'shared/dossiers/edit', type: :view do
before do
allow(dossier).to receive(:can_passer_en_construction?).and_return(false)
allow(dossier.revision).to receive(:ineligibilite_enabled?).and_return(true)
end
it 'renders broken transitions rules dialog' do