From 08a2a2c9aa2f75596bdb4d80ce58d2b24c18f50a Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 21 Mar 2023 18:24:39 +0100 Subject: [PATCH] feat(dossier): fork dossier when editing en construction --- .../autosave_footer_component.html.haml | 18 +-- .../dossiers/edit_footer_component.rb | 10 +- .../edit_footer_component.en.yml | 1 + .../edit_footer_component.fr.yml | 1 + .../edit_footer_component.html.haml | 5 +- .../champ_label_component.html.haml | 2 +- .../champ_label_content_component.html.haml | 5 +- .../concerns/turbo_champs_concern.rb | 2 +- app/controllers/users/dossiers_controller.rb | 46 +++--- app/models/champ.rb | 4 + app/views/shared/dossiers/_edit.html.haml | 16 +- .../users/dossiers/update.turbo_stream.haml | 10 +- config/routes.rb | 4 +- .../users/dossiers_controller_spec.rb | 143 ++++++++++++------ spec/system/routing/full_scenario_spec.rb | 4 + .../routing/rules_full_scenario_spec.rb | 4 + spec/system/users/brouillon_spec.rb | 4 +- spec/system/users/dossier_shared_examples.rb | 1 + spec/system/users/en_construction_spec.rb | 8 +- .../shared/dossiers/_edit.html.haml_spec.rb | 4 +- 20 files changed, 193 insertions(+), 99 deletions(-) diff --git a/app/components/dossiers/autosave_footer_component/autosave_footer_component.html.haml b/app/components/dossiers/autosave_footer_component/autosave_footer_component.html.haml index 62f95893c..733e691a0 100644 --- a/app/components/dossiers/autosave_footer_component/autosave_footer_component.html.haml +++ b/app/components/dossiers/autosave_footer_component/autosave_footer_component.html.haml @@ -3,10 +3,10 @@ %span.autosave-explanation-text - if annotation? = t('.annotations.explanation') - - elsif dossier.brouillon? - = t('.brouillon.explanation') - - else + - elsif dossier.editing_fork? = t('.en_construction.explanation') + - else + = t('.brouillon.explanation') - if !annotation? = link_to t('.more_information'), t("links.common.faq.autosave_url"), class: 'autosave-more-infos fr-link fr-link--sm', **external_link_attributes @@ -15,10 +15,10 @@ %span.autosave-label - if annotation? = t('.annotations.confirmation') - - elsif dossier.brouillon? - = t('.brouillon.confirmation') - - else + - elsif dossier.editing_fork? = t('.en_construction.confirmation') + - else + = t('.brouillon.confirmation') - if !annotation? = link_to t('.more_information'), t("links.common.faq.autosave_url"), class: 'autosave-more-infos fr-link fr-link--sm', **external_link_attributes @@ -27,10 +27,10 @@ %span.autosave-label - if annotation? = t('.annotations.error') - - elsif dossier.brouillon? - = t('.brouillon.error') - - else + - elsif dossier.editing_fork? = t('.en_construction.error') + - else + = t('.brouillon.error') %button.button.small.autosave-retry{ type: :button, data: { action: 'autosave-status#onClickRetryButton', autosave_status_target: 'retryButton' } } %span.autosave-retry-label réessayer %span.autosave-retrying-label enregistrement en cours… diff --git a/app/components/dossiers/edit_footer_component.rb b/app/components/dossiers/edit_footer_component.rb index cf43539bb..0e7fc0128 100644 --- a/app/components/dossiers/edit_footer_component.rb +++ b/app/components/dossiers/edit_footer_component.rb @@ -14,7 +14,7 @@ class Dossiers::EditFooterComponent < ApplicationComponent @annotation.present? end - def button_options + def submit_draft_button_options { class: 'fr-btn fr-btn--sm', disabled: !owner?, @@ -23,6 +23,14 @@ class Dossiers::EditFooterComponent < ApplicationComponent } end + def submit_en_construction_button_options + { + class: 'fr-btn fr-btn--sm', + method: :post, + data: { 'disable-with': t('.submitting'), controller: 'autosave-submit' } + } + end + def render? !@dossier.for_procedure_preview? end diff --git a/app/components/dossiers/edit_footer_component/edit_footer_component.en.yml b/app/components/dossiers/edit_footer_component/edit_footer_component.en.yml index 42f2cce41..c6b8c398d 100644 --- a/app/components/dossiers/edit_footer_component/edit_footer_component.en.yml +++ b/app/components/dossiers/edit_footer_component/edit_footer_component.en.yml @@ -1,5 +1,6 @@ --- en: submit: Submit the file + submit_changes: Submit file changes submitting: Submitting… invite_notice: You are invited to make amendments to this file but only the owner themselves can submit it. diff --git a/app/components/dossiers/edit_footer_component/edit_footer_component.fr.yml b/app/components/dossiers/edit_footer_component/edit_footer_component.fr.yml index c57af8f8d..decf8b3fc 100644 --- a/app/components/dossiers/edit_footer_component/edit_footer_component.fr.yml +++ b/app/components/dossiers/edit_footer_component/edit_footer_component.fr.yml @@ -1,5 +1,6 @@ --- fr: submit: Déposer le dossier + submit_changes: Déposer les modifications submitting: Envoi en cours… invite_notice: En tant qu’invité, vous pouvez remplir ce formulaire – mais le titulaire du dossier doit le déposer lui-même. diff --git a/app/components/dossiers/edit_footer_component/edit_footer_component.html.haml b/app/components/dossiers/edit_footer_component/edit_footer_component.html.haml index 803255861..277fb5d0b 100644 --- a/app/components/dossiers/edit_footer_component/edit_footer_component.html.haml +++ b/app/components/dossiers/edit_footer_component/edit_footer_component.html.haml @@ -3,7 +3,10 @@ = render Dossiers::AutosaveFooterComponent.new(dossier: @dossier, annotation: annotation?) - if !annotation? && @dossier.can_transition_to_en_construction? - = button_to t('.submit'), brouillon_dossier_url(@dossier), button_options + = button_to t('.submit'), brouillon_dossier_url(@dossier), submit_draft_button_options + - elsif @dossier.forked_with_changes? + = button_to t('.submit_changes'), modifier_dossier_url(@dossier.editing_fork_origin), submit_en_construction_button_options + - if @dossier.brouillon? && !owner? .send-notice.invite-cannot-submit diff --git a/app/components/editable_champ/champ_label_component/champ_label_component.html.haml b/app/components/editable_champ/champ_label_component/champ_label_component.html.haml index 3bcd17000..d860df314 100644 --- a/app/components/editable_champ/champ_label_component/champ_label_component.html.haml +++ b/app/components/editable_champ/champ_label_component/champ_label_component.html.haml @@ -3,7 +3,7 @@ = @form.label @champ.main_value_name, id: @champ.labelledby_id, for: @champ.input_id do - render EditableChamp::ChampLabelContentComponent.new champ: @champ, seen_at: @seen_at - else - .form-label.mb-4 + .form-label.mb-4{ id: @champ.labelledby_id } = render EditableChamp::ChampLabelContentComponent.new champ: @champ, seen_at: @seen_at - if @champ.description.present? diff --git a/app/components/editable_champ/champ_label_content_component/champ_label_content_component.html.haml b/app/components/editable_champ/champ_label_content_component/champ_label_content_component.html.haml index c26b10a26..eeac93d00 100644 --- a/app/components/editable_champ/champ_label_content_component/champ_label_content_component.html.haml +++ b/app/components/editable_champ/champ_label_content_component/champ_label_content_component.html.haml @@ -2,7 +2,10 @@ - if @champ.mandatory? %span.mandatory * -- if @champ.updated_at.present? && @seen_at.present? +- if @champ.forked_with_changes? + %span.updated-at.highlighted + = @champ.updated_at > 1.minutes.ago ? "modifié à l’instant" : "modification à déposer" +- elsif @champ.updated_at.present? && @seen_at.present? %span.updated-at{ class: highlight_if_unseen_class } = "modifié le #{try_format_datetime(@champ.updated_at)}" diff --git a/app/controllers/concerns/turbo_champs_concern.rb b/app/controllers/concerns/turbo_champs_concern.rb index abb60bbff..af5be0438 100644 --- a/app/controllers/concerns/turbo_champs_concern.rb +++ b/app/controllers/concerns/turbo_champs_concern.rb @@ -6,7 +6,7 @@ module TurboChampsConcern def champs_to_turbo_update(params, champs) champ_ids = params.keys.map(&:to_i) - to_update = champs.filter { _1.id.in?(champ_ids) && _1.refresh_after_update? } + to_update = champs.filter { _1.id.in?(champ_ids) && (_1.refresh_after_update? || _1.forked_with_changes?) } to_show, to_hide = champs.filter(&:conditional?) .partition(&:visible?) .map { champs_to_one_selector(_1 - to_update) } diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index 8af994e31..9371adc24 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -6,12 +6,12 @@ module Users layout 'procedure_context', only: [:identite, :update_identite, :siret, :update_siret] ACTIONS_ALLOWED_TO_ANY_USER = [:index, :recherche, :new, :transferer_all] - ACTIONS_ALLOWED_TO_OWNER_OR_INVITE = [:show, :destroy, :demande, :messagerie, :brouillon, :update_brouillon, :submit_brouillon, :modifier, :update, :create_commentaire, :papertrail, :restore] + ACTIONS_ALLOWED_TO_OWNER_OR_INVITE = [:show, :destroy, :demande, :messagerie, :brouillon, :submit_brouillon, :submit_en_construction, :modifier, :update, :create_commentaire, :papertrail, :restore] before_action :ensure_ownership!, except: ACTIONS_ALLOWED_TO_ANY_USER + ACTIONS_ALLOWED_TO_OWNER_OR_INVITE before_action :ensure_ownership_or_invitation!, only: ACTIONS_ALLOWED_TO_OWNER_OR_INVITE - before_action :ensure_dossier_can_be_updated, only: [:update_identite, :update_siret, :brouillon, :update_brouillon, :submit_brouillon, :modifier, :update] - before_action :ensure_dossier_can_be_filled, only: [:brouillon, :modifier, :update_brouillon, :submit_brouillon, :update] + before_action :ensure_dossier_can_be_updated, only: [:update_identite, :update_siret, :brouillon, :submit_brouillon, :submit_en_construction, :modifier, :update] + before_action :ensure_dossier_can_be_filled, only: [:brouillon, :modifier, :submit_brouillon, :submit_en_construction, :update] before_action :ensure_dossier_can_be_viewed, only: [:show] before_action :forbid_invite_submission!, only: [:submit_brouillon] before_action :forbid_closed_submission!, only: [:submit_brouillon] @@ -202,21 +202,30 @@ module Users @dossier = dossier_with_champs end - def update_brouillon - @dossier = dossier_with_champs - update_dossier_and_compute_errors + def submit_en_construction + @dossier = dossier.find_editing_fork(dossier.user) + @dossier = dossier_with_champs(pj_template: false) + errors = submit_dossier_and_compute_errors - respond_to do |format| - format.html { render :brouillon } - format.turbo_stream do - @to_show, @to_hide, @to_update = champs_to_turbo_update(champs_public_params.fetch(:champs_public_all_attributes), dossier.champs_public_all) + if errors.blank? + editing_fork_origin = @dossier.editing_fork_origin + editing_fork_origin.merge_fork(@dossier) + redirect_to dossier_path(editing_fork_origin) + else + flash.now.alert = errors - render(:update, layout: false) + respond_to do |format| + format.html { render :modifier } + format.turbo_stream do + @to_show, @to_hide, @to_update = champs_to_turbo_update(champs_public_params.fetch(:champs_public_all_attributes), dossier.champs_public_all) + render :update, layout: false + end end end end def update + @dossier = dossier.en_construction? ? dossier.find_editing_fork(dossier.user) : dossier @dossier = dossier_with_champs(pj_template: false) errors = update_dossier_and_compute_errors @@ -225,9 +234,9 @@ module Users end respond_to do |format| - format.html { render :modifier } format.turbo_stream do @to_show, @to_hide, @to_update = champs_to_turbo_update(champs_public_params.fetch(:champs_public_all_attributes), dossier.champs_public_all) + render :update, layout: false end end end @@ -425,8 +434,8 @@ module Users end def dossier_scope - if action_name == 'update_brouillon' - Dossier.visible_by_user.or(Dossier.for_procedure_preview) + if action_name == 'update' + Dossier.visible_by_user.or(Dossier.for_procedure_preview).or(Dossier.for_editing_fork) elsif action_name == 'restore' Dossier.hidden_by_user else @@ -488,10 +497,6 @@ module Users RoutingEngine.compute(@dossier) end - if dossier.en_construction? - errors += format_errors(errors: @dossier.check_mandatory_and_visible_champs) - end - errors end @@ -528,9 +533,12 @@ module Users def append_anchor_link(str_error, model) return str_error.full_message if !model.is_a?(Champ) + + route_helper = @dossier.editing_fork? ? :modifier_dossier_path : :brouillon_dossier_path + [ "Le champ « #{model.libelle.truncate(200)} » #{str_error}", - helpers.link_to(t('views.users.dossiers.fix_champ'), brouillon_dossier_path(anchor: model.input_id)) + helpers.link_to(t('views.users.dossiers.fix_champ'), public_send(route_helper, anchor: model.input_id)) ].join(", ") rescue # case of invalid type de champ on champ str_error diff --git a/app/models/champ.rb b/app/models/champ.rb index 15ed9079c..3113e73a0 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -244,6 +244,10 @@ class Champ < ApplicationRecord input_id end + def forked_with_changes? + public? && dossier.champ_forked_with_changes?(self) + end + private def html_id diff --git a/app/views/shared/dossiers/_edit.html.haml b/app/views/shared/dossiers/_edit.html.haml index 647d9ba16..083c9b78e 100644 --- a/app/views/shared/dossiers/_edit.html.haml +++ b/app/views/shared/dossiers/_edit.html.haml @@ -1,17 +1,13 @@ +- dossier_for_editing = dossier.en_construction? ? dossier.owner_editing_fork : dossier + - if dossier.france_connect_information.present? - content_for(:notice_info) do = render partial: "shared/dossiers/france_connect_informations_notice", locals: { user_information: dossier.france_connect_information } .dossier-edit.container.counter-start-header-section = render partial: "shared/dossiers/submit_is_over", locals: { dossier: dossier } - - - if dossier.brouillon? - - form_options = { url: brouillon_dossier_url(dossier), method: :patch } - - else - - form_options = { url: modifier_dossier_url(dossier), method: :patch } = render NestedForms::FormOwnerComponent.new - = form_for dossier, form_options.merge({ html: { id: 'dossier-edit-form', class: 'form', multipart: true, novalidate: 'novalidate' } }) do |f| - + = form_for dossier_for_editing, url: brouillon_dossier_url(dossier), method: :patch, html: { id: 'dossier-edit-form', class: 'form', multipart: true, novalidate: 'novalidate' } do |f| %header.mb-6 .fr-highlight %p.fr-text--sm @@ -42,5 +38,7 @@ = f.select :groupe_instructeur_id, dossier.procedure.groupe_instructeurs.active.map { |gi| [gi.label, gi.id] }, { include_blank: dossier.brouillon? } - = render EditableChamp::SectionComponent.new(champs: dossier.champs_public) - = render Dossiers::EditFooterComponent.new(dossier: dossier, annotation: false) + + + = render EditableChamp::SectionComponent.new(champs: dossier_for_editing.champs_public) + = render Dossiers::EditFooterComponent.new(dossier: dossier_for_editing, annotation: false) diff --git a/app/views/users/dossiers/update.turbo_stream.haml b/app/views/users/dossiers/update.turbo_stream.haml index ce7539ab1..a8daa34cb 100644 --- a/app/views/users/dossiers/update.turbo_stream.haml +++ b/app/views/users/dossiers/update.turbo_stream.haml @@ -4,8 +4,14 @@ = turbo_stream.hide_all(@to_hide) - @to_update.each do |champ| = fields_for champ.input_name, champ do |form| - = turbo_stream.replace champ.input_group_id do - = render EditableChamp::EditableChampComponent.new champ:, form: + - if champ.refresh_after_update? + = turbo_stream.replace champ.input_group_id do + = render EditableChamp::EditableChampComponent.new champ:, form: + - else + = turbo_stream.update champ.labelledby_id do + = render EditableChamp::ChampLabelContentComponent.new champ: = turbo_stream.remove_all(".editable-champ .spinner-removable"); = turbo_stream.hide_all(".editable-champ .spinner"); += turbo_stream.replace_all '.dossier-edit-sticky-footer' do + = render Dossiers::EditFooterComponent.new(dossier: @dossier, annotation: false) diff --git a/config/routes.rb b/config/routes.rb index 106ca03a8..d04bc43f0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -315,10 +315,10 @@ Rails.application.routes.draw do post 'siret', to: 'dossiers#update_siret' get 'etablissement' get 'brouillon' - patch 'brouillon', to: 'dossiers#update_brouillon' + patch 'brouillon', to: 'dossiers#update' post 'brouillon', to: 'dossiers#submit_brouillon' get 'modifier', to: 'dossiers#modifier' - patch 'modifier', to: 'dossiers#update' + post 'modifier', to: 'dossiers#submit_en_construction' get 'merci' get 'demande' get 'messagerie' diff --git a/spec/controllers/users/dossiers_controller_spec.rb b/spec/controllers/users/dossiers_controller_spec.rb index b98acd936..13c0048ab 100644 --- a/spec/controllers/users/dossiers_controller_spec.rb +++ b/spec/controllers/users/dossiers_controller_spec.rb @@ -445,11 +445,76 @@ describe Users::DossiersController, type: :controller do end end - describe '#update_brouillon' do + describe '#submit_en_construction' do before { sign_in(user) } - let(:procedure) { create(:procedure, :published, :with_type_de_champ, :with_piece_justificative) } - let!(:dossier) { create(:dossier, user: user, procedure: procedure) } + let!(:dossier) { create(:dossier, :en_construction, user: user) } + let(:first_champ) { dossier.owner_editing_fork.champs_public.first } + let(:anchor_to_first_champ) { controller.helpers.link_to I18n.t('views.users.dossiers.fix_champ'), modifier_dossier_path(anchor: first_champ.input_id) } + let(:value) { 'beautiful value' } + let(:now) { Time.zone.parse('01/01/2100') } + let(:payload) { { id: dossier.id } } + + before { dossier.owner_editing_fork } + + subject do + Timecop.freeze(now) do + post :submit_en_construction, params: payload + end + end + + context 'when the dossier cannot be updated by the user' do + let!(:dossier) { create(:dossier, :en_instruction, user: user) } + + it 'redirects to the dossiers list' do + subject + + expect(response).to redirect_to(dossier_path(dossier)) + expect(flash.alert).to eq('Votre dossier ne peut plus être modifié') + end + end + + context 'when the update fails' do + before do + expect_any_instance_of(Dossier).to receive(:valid?).and_return(false) + expect_any_instance_of(Dossier).to receive(:errors).and_return( + [double(class: ActiveModel::Error, full_message: 'nop', base: first_champ)] + ) + subject + end + + it { expect(response).to render_template(:modifier) } + it { expect(flash.alert).to eq(["Le champ « #{first_champ.libelle} » nop, #{anchor_to_first_champ}"]) } + end + + context 'when a mandatory champ is missing' do + let(:value) { nil } + + before do + first_champ.type_de_champ.update(mandatory: true, libelle: 'l') + subject + end + + it { expect(response).to render_template(:modifier) } + it { expect(flash.alert).to eq(["Le champ « l » doit être rempli, #{anchor_to_first_champ}"]) } + end + + context 'when dossier has no champ' do + let(:submit_payload) { { id: dossier.id } } + + it 'does not raise any errors' do + subject + + expect(response).to redirect_to(dossier_path(dossier)) + end + end + end + + describe '#update brouillon' do + before { sign_in(user) } + + let(:procedure) { create(:procedure, :published, types_de_champ_public: [{}, { type: :piece_justificative }]) } + let(:dossier) { create(:dossier, user:, procedure:) } let(:first_champ) { dossier.champs_public.first } let(:piece_justificative_champ) { dossier.champs_public.last } let(:value) { 'beautiful value' } @@ -461,16 +526,16 @@ describe Users::DossiersController, type: :controller do id: dossier.id, dossier: { groupe_instructeur_id: dossier.groupe_instructeur_id, - champs_public_attributes: [ - { + champs_public_attributes: { + first_champ.id => { id: first_champ.id, value: value }, - { + piece_justificative_champ.id => { id: piece_justificative_champ.id, piece_justificative_file: file } - ] + } } } end @@ -478,12 +543,12 @@ describe Users::DossiersController, type: :controller do subject do Timecop.freeze(now) do - patch :update_brouillon, params: payload + patch :update, params: payload, format: :turbo_stream end end context 'when the dossier cannot be updated by the user' do - let!(:dossier) { create(:dossier, :en_instruction, user: user) } + let(:dossier) { create(:dossier, :en_instruction, user:, procedure:) } it 'redirects to the dossiers list' do subject @@ -507,7 +572,7 @@ describe Users::DossiersController, type: :controller do { id: dossier.id, dossier: { - champs_public_attributes: [{ value: '' }] + champs_public_attributes: { first_champ.id => { id: first_champ.id } } } } end @@ -520,7 +585,7 @@ describe Users::DossiersController, type: :controller do end context 'when the user has an invitation but is not the owner' do - let(:dossier) { create(:dossier) } + let(:dossier) { create(:dossier, procedure: procedure) } let!(:invite) { create(:invite, dossier: dossier, user: user) } before { subject } @@ -530,11 +595,11 @@ describe Users::DossiersController, type: :controller do end end - describe '#update' do + describe '#update en_construction' do before { sign_in(user) } - let(:procedure) { create(:procedure, :published, :with_type_de_champ, :with_piece_justificative) } - let!(:dossier) { create(:dossier, :en_construction, user: user, procedure: procedure) } + let(:procedure) { create(:procedure, :published, types_de_champ_public: [{}, { type: :piece_justificative }]) } + let!(:dossier) { create(:dossier, :en_construction, user:, procedure:) } let(:first_champ) { dossier.champs_public.first } let(:anchor_to_first_champ) { controller.helpers.link_to I18n.t('views.users.dossiers.fix_champ'), brouillon_dossier_path(anchor: first_champ.input_id) } let(:piece_justificative_champ) { dossier.champs_public.last } @@ -547,16 +612,16 @@ describe Users::DossiersController, type: :controller do id: dossier.id, dossier: { groupe_instructeur_id: dossier.groupe_instructeur_id, - champs_public_attributes: [ - { + champs_public_attributes: { + first_champ.id => { id: first_champ.id, value: value }, - { + piece_justificative_champ.id => { id: piece_justificative_champ.id, piece_justificative_file: file } - ] + } } } end @@ -564,12 +629,12 @@ describe Users::DossiersController, type: :controller do subject do Timecop.freeze(now) do - patch :update, params: payload + patch :update, params: payload, format: :turbo_stream end end context 'when the dossier cannot be updated by the user' do - let!(:dossier) { create(:dossier, :en_instruction, user: user) } + let!(:dossier) { create(:dossier, :en_instruction, user:, procedure:) } it 'redirects to the dossiers list' do subject @@ -612,12 +677,12 @@ describe Users::DossiersController, type: :controller do { id: dossier.id, dossier: { - champs_public_attributes: [ - { + champs_public_attributes: { + piece_justificative_champ.id => { id: piece_justificative_champ.id, piece_justificative_file: file } - ] + } } } end @@ -640,7 +705,7 @@ describe Users::DossiersController, type: :controller do subject end - it { expect(response).to render_template(:modifier) } + it { expect(response).to render_template(:update) } it { expect(flash.alert).to eq(["Le champ « #{first_champ.libelle} » nop, #{anchor_to_first_champ}"]) } it 'does not update the dossier timestamps' do @@ -656,18 +721,6 @@ describe Users::DossiersController, type: :controller do end end - context 'when a mandatory champ is missing' do - let(:value) { nil } - - before do - first_champ.type_de_champ.update(mandatory: true, libelle: 'l') - subject - end - - it { expect(response).to render_template(:modifier) } - it { expect(flash.alert).to eq(["Le champ « l » doit être rempli, #{anchor_to_first_champ}"]) } - end - context 'when a champ validation fails' do let(:value) { 'abc' } @@ -682,8 +735,8 @@ describe Users::DossiersController, type: :controller do end context 'when the user has an invitation but is not the owner' do - let(:dossier) { create(:dossier, :en_construction) } - let!(:invite) { create(:invite, dossier: dossier, user: user) } + let(:dossier) { create(:dossier, :en_construction, procedure:) } + let!(:invite) { create(:invite, dossier:, user:) } before { subject } @@ -692,9 +745,9 @@ describe Users::DossiersController, type: :controller do end context 'when the dossier is followed by an instructeur' do - let(:dossier) { create(:dossier) } + let(:dossier) { create(:dossier, procedure:) } let(:instructeur) { create(:instructeur) } - let!(:invite) { create(:invite, dossier: dossier, user: user) } + let!(:invite) { create(:invite, dossier:, user:) } before do instructeur.follow(dossier) @@ -708,8 +761,8 @@ describe Users::DossiersController, type: :controller do end context 'when the champ is a phone number' do - let(:procedure) { create(:procedure, :published, :with_phone) } - let!(:dossier) { create(:dossier, :en_construction, user: user, procedure: procedure) } + let(:procedure) { create(:procedure, :published, types_de_champ_public: [{ type: :phone }]) } + let!(:dossier) { create(:dossier, :en_construction, user:, procedure:) } let(:first_champ) { dossier.champs_public.first } let(:now) { Time.zone.parse('01/01/2100') } @@ -717,12 +770,12 @@ describe Users::DossiersController, type: :controller do { id: dossier.id, dossier: { - champs_public_attributes: [ - { + champs_public_attributes: { + first_champ.id => { id: first_champ.id, value: value } - ] + } } } end diff --git a/spec/system/routing/full_scenario_spec.rb b/spec/system/routing/full_scenario_spec.rb index 4524d22f7..a6f27891f 100644 --- a/spec/system/routing/full_scenario_spec.rb +++ b/spec/system/routing/full_scenario_spec.rb @@ -119,6 +119,8 @@ describe 'The routing', js: true do fill_in litteraire_user.dossiers.first.champs_public.first.libelle, with: 'some value' wait_for_autosave(false) + click_on 'Déposer les modifications' + log_out # the litteraires instructeurs should have a notification @@ -217,6 +219,8 @@ describe 'The routing', js: true do expect(page).to have_text(new_group) + click_on 'Déposer les modifications' + log_out end diff --git a/spec/system/routing/rules_full_scenario_spec.rb b/spec/system/routing/rules_full_scenario_spec.rb index 01e3d28e2..b643ba225 100644 --- a/spec/system/routing/rules_full_scenario_spec.rb +++ b/spec/system/routing/rules_full_scenario_spec.rb @@ -146,6 +146,8 @@ describe 'The routing with rules', js: true do fill_in litteraire_user.dossiers.first.champs_public.first.libelle, with: 'some value' wait_for_autosave(false) + click_on 'Déposer les modifications' + log_out # the litteraires instructeurs should have a notification @@ -245,6 +247,8 @@ describe 'The routing with rules', js: true do expect(page).to have_text(new_group) + click_on 'Déposer les modifications' + log_out end diff --git a/spec/system/users/brouillon_spec.rb b/spec/system/users/brouillon_spec.rb index f8d1b8f6e..3d1fdd850 100644 --- a/spec/system/users/brouillon_spec.rb +++ b/spec/system/users/brouillon_spec.rb @@ -483,13 +483,13 @@ describe 'The user' do fill_individual # Test autosave failure - allow_any_instance_of(Users::DossiersController).to receive(:update_brouillon).and_raise("Server is busy") + allow_any_instance_of(Users::DossiersController).to receive(:update).and_raise("Server is busy") fill_in('texte obligatoire', with: 'a valid user input') blur expect(page).to have_css('span', text: 'Impossible d’enregistrer le brouillon', visible: true) # Test that retrying after a failure works - allow_any_instance_of(Users::DossiersController).to receive(:update_brouillon).and_call_original + allow_any_instance_of(Users::DossiersController).to receive(:update).and_call_original click_on 'réessayer' wait_for_autosave diff --git a/spec/system/users/dossier_shared_examples.rb b/spec/system/users/dossier_shared_examples.rb index 1f212d450..ee50b85f6 100644 --- a/spec/system/users/dossier_shared_examples.rb +++ b/spec/system/users/dossier_shared_examples.rb @@ -12,6 +12,7 @@ RSpec.shared_examples 'the user can edit the submitted demande' do fill_in('Texte obligatoire', with: 'Nouveau texte') wait_for_autosave(false) + click_on 'Déposer les modifications' click_on 'Demande' expect(page).to have_current_path(demande_dossier_path(dossier)) diff --git a/spec/system/users/en_construction_spec.rb b/spec/system/users/en_construction_spec.rb index 51d3ded7c..36b494848 100644 --- a/spec/system/users/en_construction_spec.rb +++ b/spec/system/users/en_construction_spec.rb @@ -8,7 +8,7 @@ describe "Dossier en_construction" do } let(:champ) { - dossier.champs_public.find { _1.type_de_champ_id == tdc.id } + dossier.find_editing_fork(dossier.user).champs_public.find { _1.type_de_champ_id == tdc.id } } scenario 'delete a non mandatory piece justificative', js: true do @@ -28,7 +28,7 @@ describe "Dossier en_construction" do scenario 'remplace a mandatory piece justificative', js: true do visit_dossier(dossier) - click_on "Remplacer le fichier toto.txt" + click_on "Supprimer le fichier toto.txt" input_selector = "#attachment-multiple-empty-#{champ.id}" expect(page).to have_selector(input_selector) @@ -51,9 +51,9 @@ describe "Dossier en_construction" do scenario 'remplace a mandatory titre identite', js: true do visit_dossier(dossier) - click_on "Remplacer le fichier toto.png" + click_on "Supprimer le fichier toto.png" - input_selector = ".attachment-input-#{champ.piece_justificative_file.attachments.first.id}" + input_selector = "##{champ.input_id}" expect(page).to have_selector(input_selector) find(input_selector).attach_file(Rails.root.join('spec/fixtures/files/file.pdf')) diff --git a/spec/views/shared/dossiers/_edit.html.haml_spec.rb b/spec/views/shared/dossiers/_edit.html.haml_spec.rb index 64bde6cea..ae5108669 100644 --- a/spec/views/shared/dossiers/_edit.html.haml_spec.rb +++ b/spec/views/shared/dossiers/_edit.html.haml_spec.rb @@ -115,8 +115,8 @@ describe 'shared/dossiers/edit', type: :view do let(:dossier) { create(:dossier, :en_construction) } before { dossier.champs_public << champ } - it 'cannot delete a piece justificative' do - expect(subject).not_to have_selector("[title='Supprimer le fichier #{champ.piece_justificative_file.attachments[0].filename}']") + it 'can delete a piece justificative' do + expect(subject).to have_selector("[title='Supprimer le fichier #{champ.piece_justificative_file.attachments[0].filename}']") end end