From c4403bffeb8fa2c435aaac3f89ce1cb5507b4bee Mon Sep 17 00:00:00 2001 From: simon lehericey Date: Mon, 15 Jul 2024 23:26:49 +0200 Subject: [PATCH] work on controller --- .../export_templates_controller.rb | 72 +++----- .../export_templates_controller_spec.rb | 159 +++++++++++------- 2 files changed, 119 insertions(+), 112 deletions(-) diff --git a/app/controllers/instructeurs/export_templates_controller.rb b/app/controllers/instructeurs/export_templates_controller.rb index 64ef44a4e..65a4c7dc5 100644 --- a/app/controllers/instructeurs/export_templates_controller.rb +++ b/app/controllers/instructeurs/export_templates_controller.rb @@ -1,21 +1,18 @@ module Instructeurs class ExportTemplatesController < InstructeurController - before_action :set_procedure - before_action :set_groupe_instructeur, only: [:create, :update] + before_action :set_procedure_and_groupe_instructeurs before_action :set_export_template, only: [:edit, :update, :destroy] - before_action :set_groupe_instructeurs - before_action :set_all_pj + before_action :ensure_legitimate_groupe_instructeur, only: [:create, :update] def new - @export_template = ExportTemplate.new(kind: 'zip', groupe_instructeur: @groupe_instructeurs.first) - @export_template.set_default_values + @export_template = ExportTemplate.default(groupe_instructeur: @groupe_instructeurs.first) end def create - @export_template = @groupe_instructeur.export_templates.build(export_template_params) - @export_template.assign_pj_names(pj_params) + @export_template = ExportTemplate.new(export_template_params) + if @export_template.save - redirect_to exports_instructeur_procedure_path(procedure: @procedure), notice: "Le modèle d'export #{@export_template.name} a bien été créé" + redirect_to [:exports, :instructeur, @procedure], notice: "Le modèle d'export #{@export_template.name} a bien été créé" else flash[:alert] = @export_template.errors.full_messages render :new @@ -26,11 +23,8 @@ module Instructeurs end def update - @export_template.assign_attributes(export_template_params) - @export_template.groupe_instructeur = @groupe_instructeur - @export_template.assign_pj_names(pj_params) - if @export_template.save - redirect_to exports_instructeur_procedure_path(procedure: @procedure), notice: "Le modèle d'export #{@export_template.name} a bien été modifié" + if @export_template.update(export_template_params) + redirect_to [:exports, :instructeur, @procedure], notice: "Le modèle d'export #{@export_template.name} a bien été modifié" else flash[:alert] = @export_template.errors.full_messages render :edit @@ -39,62 +33,40 @@ module Instructeurs def destroy if @export_template.destroy - redirect_to exports_instructeur_procedure_path(procedure: @procedure), notice: "Le modèle d'export #{@export_template.name} a bien été supprimé" + redirect_to [:exports, :instructeur, @procedure], notice: "Le modèle d'export #{@export_template.name} a bien été supprimé" else - redirect_to exports_instructeur_procedure_path(procedure: @procedure), alert: "Le modèle d'export #{@export_template.name} n'a pu être supprimé" + redirect_to [:exports, :instructeur, @procedure], alert: "Le modèle d'export #{@export_template.name} n'a pu être supprimé" end end def preview - set_groupe_instructeur - @export_template = @groupe_instructeur.export_templates.build(export_template_params) - @export_template.assign_pj_names(pj_params) + export_template = ExportTemplate.new(export_template_params) - @sample_dossier = @procedure.dossier_for_preview(current_instructeur) - - render turbo_stream: turbo_stream.replace('preview', partial: 'preview', locals: { export_template: @export_template, procedure: @procedure, dossier: @sample_dossier }) + render turbo_stream: turbo_stream.replace('preview', partial: 'preview', locals: { export_template: }) end private def export_template_params - params.require(:export_template).permit(*export_params) + params.require(:export_template) + .permit(:name, :kind, :groupe_instructeur_id, dossier_folder: [:enabled, :template], export_pdf: [:enabled, :template], pjs: [:stable_id, :enabled, :template]) end - def set_procedure - @procedure = current_instructeur.procedures.find params[:procedure_id] - Sentry.configure_scope do |scope| - scope.set_tags(procedure: @procedure.id) - end + def set_procedure_and_groupe_instructeurs + @procedure = current_instructeur.procedures.find(params[:procedure_id]) + @groupe_instructeurs = current_instructeur.groupe_instructeurs.where(procedure: @procedure) + + Sentry.configure_scope { |scope| scope.set_tags(procedure: @procedure.id) } end def set_export_template @export_template = current_instructeur.export_templates.find(params[:id]) end - def set_groupe_instructeur - @groupe_instructeur = @procedure.groupe_instructeurs.find(params.require(:export_template)[:groupe_instructeur_id]) - end + def ensure_legitimate_groupe_instructeur + return if export_template_params[:groupe_instructeur_id].in?(@groupe_instructeurs.map { _1.id.to_s }) - def set_groupe_instructeurs - @groupe_instructeurs = current_instructeur.groupe_instructeurs.where(procedure: @procedure) - end - - def set_all_pj - @all_pj ||= @procedure.exportables_pieces_jointes - end - - def export_params - [:name, :kind, :tiptap_default_dossier_directory, :tiptap_pdf_name] - end - - def pj_params - @procedure = current_instructeur.procedures.find params[:procedure_id] - pj_params = [] - @all_pj.each do |pj| - pj_params << "tiptap_pj_#{pj.stable_id}".to_sym - end - params.require(:export_template).permit(*pj_params) + redirect_to [:exports, :instructeur, @procedure], alert: 'Vous n’avez pas le droit de créer un modèle d’export pour ce groupe' end end end diff --git a/spec/controllers/instructeurs/export_templates_controller_spec.rb b/spec/controllers/instructeurs/export_templates_controller_spec.rb index 36c9f665e..df19aa1b4 100644 --- a/spec/controllers/instructeurs/export_templates_controller_spec.rb +++ b/spec/controllers/instructeurs/export_templates_controller_spec.rb @@ -1,58 +1,31 @@ describe Instructeurs::ExportTemplatesController, type: :controller do before { sign_in(instructeur.user) } - let(:tiptap_pdf_name) { - { - "type" => "doc", - "content" => [ - { "type" => "paragraph", "content" => [{ "text" => "mon_export_", "type" => "text" }, { "type" => "mention", "attrs" => { "id" => "dossier_number", "label" => "numéro du dossier" } }] } - ] - }.to_json - } - - let(:export_template_params) do - { - name: "coucou", - kind: "zip", - groupe_instructeur_id: groupe_instructeur.id, - tiptap_pdf_name: tiptap_pdf_name, - tiptap_default_dossier_directory: { - "type" => "doc", - "content" => [ - { "type" => "paragraph", "content" => [{ "text" => "DOSSIER_", "type" => "text" }, { "type" => "mention", "attrs" => { "id" => "dossier_number", "label" => "numéro du dossier" } }, { "text" => " ", "type" => "text" }] } - ] - }.to_json, - tiptap_pj_3: { - "type" => "doc", - "content" => [{ "type" => "paragraph", "content" => [{ "type" => "text", "text" => "avis-commission-" }, { "type" => "mention", "attrs" => { "id" => "dossier_number", "label" => "numéro du dossier" } }] }] - }.to_json, - tiptap_pj_5: { - - "type" => "doc", - "content" => [{ "type" => "paragraph", "content" => [{ "type" => "text", "text" => "avis-commission-" }, { "type" => "mention", "attrs" => { "id" => "dossier_number", "label" => "numéro du dossier" } }] }] - }.to_json, - tiptap_pj_10: { - - "type" => "doc", - "content" => [{ "type" => "paragraph", "content" => [{ "type" => "text", "text" => "avis-commission-" }, { "type" => "mention", "attrs" => { "id" => "dossier_number", "label" => "numéro du dossier" } }] }] - }.to_json - } - end let(:instructeur) { create(:instructeur) } let(:procedure) do create( :procedure, instructeurs: [instructeur], - types_de_champ_public: [ - { type: :piece_justificative, libelle: "pj1", stable_id: 3 }, - { type: :piece_justificative, libelle: "pj2", stable_id: 5 }, - { type: :piece_justificative, libelle: "pj3", stable_id: 10 } - ] + types_de_champ_public: [{ type: :piece_justificative, libelle: "pj1", stable_id: 3 }] ) end let(:groupe_instructeur) { procedure.defaut_groupe_instructeur } + let(:groupe_instructeur_id) { groupe_instructeur.id } + + let(:export_template_params) do + { + name: "coucou", + kind: "zip", + groupe_instructeur_id:, + export_pdf:, + dossier_folder: item_params(text: "DOSSIER_"), + pjs: [pj_item_params(stable_id: 3, text: "avis-commission-"), pj_item_params(stable_id: 666, text: "evil-hack")] + } + end + + let(:export_pdf) { item_params(text: "mon_export_") } describe '#new' do - let(:subject) { get :new, params: { procedure_id: procedure.id } } + subject { get :new, params: { procedure_id: procedure.id } } it do subject @@ -61,18 +34,22 @@ describe Instructeurs::ExportTemplatesController, type: :controller do end describe '#create' do - let(:subject) { post :create, params: { procedure_id: procedure.id, export_template: export_template_params } } + let(:create_params) { export_template_params } + subject { post :create, params: { procedure_id: procedure.id, export_template: create_params } } context 'with valid params' do it 'redirect to some page' do subject - expect(response).to redirect_to(exports_instructeur_procedure_path(procedure:)) + expect(response).to redirect_to(exports_instructeur_procedure_path(procedure)) expect(flash.notice).to eq "Le modèle d'export coucou a bien été créé" end end context 'with invalid params' do - let(:tiptap_pdf_name) { { content: "invalid" }.to_json } + let(:export_pdf) do + item_params(text: 'toto').merge("template" => { "content" => [{ "content" => "invalid" }] }.to_json) + end + it 'display error notification' do subject expect(flash.alert).to be_present @@ -81,16 +58,37 @@ describe Instructeurs::ExportTemplatesController, type: :controller do context 'with procedure not accessible by current instructeur' do let(:another_procedure) { create(:procedure) } - let(:subject) { post :create, params: { procedure_id: another_procedure.id, export_template: export_template_params } } + subject { post :create, params: { procedure_id: another_procedure.id, export_template: export_template_params } } + it 'raise exception' do expect { subject }.to raise_error(ActiveRecord::RecordNotFound) end end + + context 'with invalid groupe_instructeur_id' do + let(:groupe_instructeur_id) { create(:groupe_instructeur).id } + + it 'display error notification' do + expect { subject }.not_to change(ExportTemplate, :count) + expect(flash.alert).to be_present + end + end + + context 'without pjs' do + let(:create_params) { export_template_params.tap { _1.delete(:pjs) } } + + it 'works' do + subject + + expect(flash.notice).to eq "Le modèle d'export coucou a bien été créé" + expect(ExportTemplate.last.pjs).to match_array([]) + end + end end describe '#edit' do let(:export_template) { create(:export_template, groupe_instructeur:) } - let(:subject) { get :edit, params: { procedure_id: procedure.id, id: export_template.id } } + subject { get :edit, params: { procedure_id: procedure.id, id: export_template.id } } it 'render edit' do subject @@ -109,42 +107,53 @@ describe Instructeurs::ExportTemplatesController, type: :controller do describe '#update' do let(:export_template) { create(:export_template, groupe_instructeur:) } - let(:tiptap_pdf_name) { - { - "type" => "doc", - "content" => [ - { "type" => "paragraph", "content" => [{ "text" => "exPort_", "type" => "text" }, { "type" => "mention", "attrs" => { "id" => "dossier_number", "label" => "numéro du dossier" } }] } - ] - }.to_json - } + let(:export_pdf) { item_params(text: "exPort_") } - let(:subject) { put :update, params: { procedure_id: procedure.id, id: export_template.id, export_template: export_template_params } } + subject { put :update, params: { procedure_id: procedure.id, id: export_template.id, export_template: export_template_params } } context 'with valid params' do it 'redirect to some page' do subject - expect(response).to redirect_to(exports_instructeur_procedure_path(procedure:)) + expect(response).to redirect_to(exports_instructeur_procedure_path(procedure)) expect(flash.notice).to eq "Le modèle d'export coucou a bien été modifié" + + export_template.reload + + expect(export_template.export_pdf.template_json).to eq(item_params(text: "exPort_")["template"]) + expect(export_template.pjs.map(&:template_json)).to eq([item_params(text: "avis-commission-")["template"]]) end end context 'with invalid params' do - let(:tiptap_pdf_name) { { content: "invalid" }.to_json } + let(:export_pdf) do + item_params(text: 'a').merge("template" => { "content" => [{ "content" => "invalid" }] }.to_json) + end + it 'display error notification' do subject expect(flash.alert).to be_present end end + + context 'with invalid groupe_instructeur_id' do + let(:groupe_instructeur_id) { create(:groupe_instructeur).id } + + it 'display error notification' do + subject + expect(export_template.export_pdf.template_json).not_to eq(item_params(text: "exPort_")["template"]) + expect(flash.alert).to be_present + end + end end describe '#destroy' do let(:export_template) { create(:export_template, groupe_instructeur:) } - let(:subject) { delete :destroy, params: { procedure_id: procedure.id, id: export_template.id } } + subject { delete :destroy, params: { procedure_id: procedure.id, id: export_template.id } } context 'with valid params' do it 'redirect to some page' do subject - expect(response).to redirect_to(exports_instructeur_procedure_path(procedure:)) + expect(response).to redirect_to(exports_instructeur_procedure_path(procedure)) expect(flash.notice).to eq "Le modèle d'export Mon export a bien été supprimé" end end @@ -155,7 +164,7 @@ describe Instructeurs::ExportTemplatesController, type: :controller do let(:export_template) { create(:export_template, groupe_instructeur:) } - let(:subject) { get :preview, params: { procedure_id: procedure.id, id: export_template.id, export_template: export_template_params }, format: :turbo_stream } + subject { get :preview, params: { procedure_id: procedure.id, id: export_template.id, export_template: export_template_params }, format: :turbo_stream } it '' do dossier = create(:dossier, procedure: procedure, for_procedure_preview: true) @@ -164,4 +173,30 @@ describe Instructeurs::ExportTemplatesController, type: :controller do expect(response.body).to include "mon_export_#{dossier.id}.pdf" end end + + def pj_item_params(stable_id:, text:, enabled: true) + item_params(text: text, enabled: enabled).merge("stable_id" => stable_id.to_s) + end + + def item_params(text:, enabled: true) + { + "enabled" => enabled, + "template" => { + "type" => "doc", + "content" => content(text:) + }.to_json + } + end + + def content(text:) + [ + { + "type" => "paragraph", + "content" => [ + { "text" => text, "type" => "text" }, + { "type" => "mention", "attrs" => { "id" => "dossier_number", "label" => "numéro du dossier" } } + ] + } + ] + end end