From d8e63221b5fdb47d15629bfc452568768452d0f3 Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Fri, 25 Oct 2024 10:27:46 +0200 Subject: [PATCH] extract a procedure_presentation controller --- .../procedure_presentation_controller.rb | 44 ++++++++++ config/routes.rb | 2 + .../procedure_presentation_controller_spec.rb | 83 +++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 app/controllers/instructeurs/procedure_presentation_controller.rb create mode 100644 spec/controllers/instructeurs/procedure_presentation_controller_spec.rb diff --git a/app/controllers/instructeurs/procedure_presentation_controller.rb b/app/controllers/instructeurs/procedure_presentation_controller.rb new file mode 100644 index 000000000..56c9e4af1 --- /dev/null +++ b/app/controllers/instructeurs/procedure_presentation_controller.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Instructeurs + class ProcedurePresentationController < InstructeurController + before_action :set_procedure_presentation + + def update + if !@procedure_presentation.update(procedure_presentation_params) + # complicated way to display inner error messages + flash.alert = @procedure_presentation.errors + .flat_map { _1.detail[:value].flat_map { |c| c.errors.full_messages } } + end + + redirect_back_or_to([:instructeur, procedure]) + end + + private + + def procedure = @procedure_presentation.procedure + + def procedure_presentation_params + filters = [ + :tous_filters, :a_suivre_filters, :suivis_filters, :traites_filters, + :expirant_filters, :archives_filters, :supprimes_filters + ].index_with { [:id, :filter] } + + h = params.permit(displayed_columns: [], sorted_column: [:order, :id], **filters).to_h + + # React ComboBox/MultiComboBox return [''] when no value is selected + # We need to remove them + if h[:displayed_columns].present? + h[:displayed_columns] = h[:displayed_columns].reject(&:empty?) + end + + h + end + + def set_procedure_presentation + @procedure_presentation = ProcedurePresentation + .includes(:assign_to) + .find_by!(id: params[:id], assign_to: { instructeur: current_instructeur }) + end + end +end diff --git a/config/routes.rb b/config/routes.rb index fc64cd041..2ab0614e4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -461,6 +461,8 @@ Rails.application.routes.draw do end end + resources :procedure_presentation, only: [:update] + resources :procedures, only: [:index, :show], param: :procedure_id do member do resources :archives, only: [:index, :create] diff --git a/spec/controllers/instructeurs/procedure_presentation_controller_spec.rb b/spec/controllers/instructeurs/procedure_presentation_controller_spec.rb new file mode 100644 index 000000000..df0548301 --- /dev/null +++ b/spec/controllers/instructeurs/procedure_presentation_controller_spec.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +describe Instructeurs::ProcedurePresentationController, type: :controller do + describe '#update' do + subject { patch :update, params: } + + let(:procedure) { create(:procedure) } + let(:instructeur) { create(:instructeur) } + let(:procedure_presentation) do + groupe_instructeur = procedure.defaut_groupe_instructeur + assign_to = create(:assign_to, instructeur:, groupe_instructeur:) + assign_to.procedure_presentation_or_default_and_errors.first + end + let(:state_column) { procedure.dossier_state_column } + + let(:params) { { id: procedure_presentation.id }.merge(presentation_params) } + + context 'nominal case' do + before { sign_in(instructeur.user) } + + let(:presentation_params) do + { + displayed_columns: [state_column.id], + sorted_column: { order: 'asc', id: state_column.id }, + tous_filters: [{ id: state_column.id, filter: 'en_construction' }] + } + end + + it 'updates the procedure_presentation' do + expect(procedure_presentation.displayed_columns).to eq(procedure.default_displayed_columns) + expect(procedure_presentation.sorted_column).to eq(procedure.default_sorted_column) + expect(procedure_presentation.tous_filters).to eq([]) + + subject + expect(response).to redirect_to(instructeur_procedure_url(procedure)) + + procedure_presentation.reload + + expect(procedure_presentation.displayed_columns).to eq([state_column]) + + expect(procedure_presentation.sorted_column.column).to eq(state_column) + expect(procedure_presentation.sorted_column.order).to eq('asc') + + filtered_column = FilteredColumn.new(column: state_column, filter: 'en_construction') + expect(procedure_presentation.tous_filters).to eq([filtered_column]) + end + end + + context 'with a wrong instructeur' do + let(:another_instructeur) { create(:instructeur) } + before { sign_in(another_instructeur.user) } + + let(:presentation_params) { { displayed_columns: [state_column.id] } } + + it 'does not update the procedure_presentation' do + expect { subject }.to raise_error(ActiveRecord::RecordNotFound) + end + end + + context 'with an empty string in displayed_columns' do + before { sign_in(instructeur.user) } + + let(:presentation_params) { { displayed_columns: [''] } } + + it 'removes the empty string' do + subject + expect(procedure_presentation.reload.displayed_columns).to eq([]) + end + end + + context 'with an error in filters' do + before { sign_in(instructeur.user) } + + let(:presentation_params) { { tous_filters: [{ id: state_column.id, filter: '' }] } } + + it 'does not update the procedure_presentation' do + subject + + expect(flash.alert).to include(/ne peut pas ĂȘtre vide/) + end + end + end +end