diff --git a/app/models/export_template.rb b/app/models/export_template.rb index eaa753415..5345116bb 100644 --- a/app/models/export_template.rb +++ b/app/models/export_template.rb @@ -3,6 +3,7 @@ class ExportTemplate < ApplicationRecord belongs_to :groupe_instructeur has_one :procedure, through: :groupe_instructeur + validates_with ExportTemplateValidator DOSSIER_STATE = Dossier.states.fetch(:en_construction) diff --git a/app/validators/export_template_validator.rb b/app/validators/export_template_validator.rb new file mode 100644 index 000000000..1f3475040 --- /dev/null +++ b/app/validators/export_template_validator.rb @@ -0,0 +1,54 @@ +class ExportTemplateValidator < ActiveModel::Validator + def validate(record) + validate_default_dossier_directory(record) + validate_pdf_name(record) + validate_pjs(record) + end + + private + + def validate_default_dossier_directory(record) + mention = attribute_content_mention(record, :default_dossier_directory) + if mention&.fetch("id", nil) != "dossier_number" + record.errors.add :tiptap_default_dossier_directory, :dossier_number_mandatory + end + end + + def validate_pdf_name(record) + if attribute_content_text(record, :pdf_name).blank? && attribute_content_mention(record, :pdf_name).blank? + record.errors.add :tiptap_pdf_name, :blank + end + end + + def attribute_content_text(record, attribute) + attribute_content(record, attribute)&.find { |elem| elem["type"] == "text" }&.fetch("text", nil) + end + + def attribute_content_mention(record, attribute) + attribute_content(record, attribute)&.find { |elem| elem["type"] == "mention" }&.fetch("attrs", nil) + end + + def attribute_content(record, attribute) + content = record.content[attribute.to_s]&.fetch("content", nil) + if content.is_a?(Array) + content.first&.fetch("content", nil) + end + end + + def validate_pjs(record) + record.content["pjs"]&.each do |pj| + pj_sym = pj.symbolize_keys + libelle = record.groupe_instructeur.procedure.pieces_jointes_exportables_list.find { _1.stable_id.to_s == pj_sym[:stable_id] }&.libelle&.to_sym + validate_content(record, pj_sym[:path], libelle) + end + end + + def validate_content(record, attribute_content, attribute) + if attribute_content.nil? || attribute_content["content"].nil? || + attribute_content["content"].first.nil? || + attribute_content["content"].first["content"].nil? || + (attribute_content["content"].first["content"].find { |elem| elem["text"].blank? } && attribute_content["content"].first["content"].find { |elem| elem["type"] == "mention" }["attrs"].blank?) + record.errors.add attribute, I18n.t(:blank, scope: 'errors.messages') + end + end +end diff --git a/spec/models/export_template_spec.rb b/spec/models/export_template_spec.rb index 9a2a29aaf..d8df04760 100644 --- a/spec/models/export_template_spec.rb +++ b/spec/models/export_template_spec.rb @@ -135,4 +135,123 @@ describe ExportTemplate do end end end + + describe '#valid?' do + let(:subject) { build(:export_template, content:) } + let(:ddd_text) { "DoSSIER" } + let(:mention) { { "type" => "mention", "attrs" => { "id" => "dossier_number", "label" => "numéro du dossier" } } } + let(:ddd_mention) { mention } + let(:pdf_text) { "export" } + let(:pdf_mention) { mention } + let(:pj_text) { "_pj" } + let(:pj_mention) { mention } + let(:content) do + { + "pdf_name" => { + "type" => "doc", + "content" => [ + { "type" => "paragraph", "content" => [{ "text" => pdf_text, "type" => "text" }, pdf_mention] } + ] + }, + "default_dossier_directory" => { + "type" => "doc", + "content" => [ + { "type" => "paragraph", "content" => [{ "text" => ddd_text, "type" => "text" }, ddd_mention] } + ] + }, + "pjs" => + [ + { path: { "type" => "doc", "content" => [{ "type" => "paragraph", "content" => [pj_mention, { "text" => pj_text, "type" => "text" }] }] }, stable_id: "3" } + ] + } + end + + context 'with valid default dossier directory' do + it 'has no error for default_dossier_directory' do + expect(subject.valid?).to be_truthy + expect(subject.errors[:default_dossier_directory]).not_to be_present + end + end + + context 'with no ddd text' do + let(:ddd_text) { " " } + context 'with mention' do + let(:ddd_mention) { { "type" => "mention", "attrs" => { "id" => "dossier_number", "label" => "numéro du dossier" } } } + it 'has no error for default_dossier_directory' do + expect(subject.valid?).to be_truthy + expect(subject.errors[:default_dossier_directory]).not_to be_present + end + end + + context 'without mention' do + let(:ddd_mention) { { "type" => "mention", "attrs" => {} } } + it "add error for default_dossier_directory" do + expect(subject.valid?).to be_falsey + expect(subject.errors[:default_dossier_directory]).to be_present + end + end + + context 'with mention but without numéro de dossier' do + let(:ddd_mention) { { "type" => "mention", "attrs" => { "id" => 'dossier_service_name', "label" => "nom du service" } } } + it "add error for default_dossier_directory" do + expect(subject.valid?).to be_falsey + expect(subject.errors[:default_dossier_directory]).to be_present + end + end + end + + context 'with valid pdf name' do + it 'has no error for pdf name' do + expect(subject.valid?).to be_truthy + expect(subject.errors[:pdf_name]).not_to be_present + end + end + + context 'with pdf text and without mention' do + let(:pdf_text) { "export" } + let(:pdf_mention) { { "type" => "mention", "attrs" => {} } } + + it "add no error" do + expect(subject.valid?).to be_truthy + end + end + + context 'with no pdf text' do + let(:pdf_text) { " " } + + context 'with mention' do + it 'has no error for default_dossier_directory' do + expect(subject.valid?).to be_truthy + expect(subject.errors[:default_dossier_directory]).not_to be_present + end + end + + context 'without mention' do + let(:pdf_mention) { { "type" => "mention", "attrs" => {} } } + it "add error for pdf name" do + expect(subject.valid?).to be_falsey + expect(subject.errors[:pdf_name]).to be_present + end + end + end + + context 'with no pj text' do + let(:pj_text) { " " } + + context 'with mention' do + it 'has no error for pj' do + expect(subject.valid?).to be_truthy + expect(subject.errors[:pj_3]).not_to be_present + end + end + + context 'without mention' do + let(:pj_mention) { { "type" => "mention", "attrs" => {} } } + it "add error for pj" do + expect(subject.valid?).to be_falsey + expect(subject.errors[:pj_3]).to be_present + end + end + end + end end