Merge pull request #8003 from tchak/feat-attestation-template-tags-validation

feat(attestation): validate attestation tags
This commit is contained in:
Paul Chavard 2022-11-23 12:46:48 +01:00 committed by GitHub
commit e00938ed63
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 265 additions and 368 deletions

View file

@ -2,4 +2,10 @@ class Procedure::Card::AttestationComponent < ApplicationComponent
def initialize(procedure:)
@procedure = procedure
end
private
def error_messages
@procedure.errors.messages_for(:attestation_template).to_sentence
end
end

View file

@ -1,10 +1,14 @@
.fr-col-6.fr-col-md-4.fr-col-lg-3
= link_to edit_admin_procedure_attestation_template_path(@procedure), class: 'fr-tile fr-enlarge-link' do
.fr-tile__body.flex.justify-between
- if @procedure.draft_attestation_template&.activated?
- if @procedure.attestation_template&.activated?
%div
%span.icon.accept
%p.fr-tile-status-accept Activée
- if error_messages.present?
%span.icon.refuse
%p.fr-tile-status-error À modifier
- else
%span.icon.accept
%p.fr-tile-status-accept Activée
- else
%div
%span.icon.clock

View file

@ -23,6 +23,8 @@ class Procedure::PublicationWarningComponent < ApplicationComponent
case attribute
when :draft_revision
champs_admin_procedure_path(@procedure)
when :attestation_template
edit_admin_procedure_attestation_template_path(@procedure)
when :initiated_mail, :received_mail, :closed_mail, :refused_mail, :without_continuation_mail
admin_procedure_mail_templates_path(@procedure)
end

View file

@ -2,53 +2,56 @@ module Administrateurs
class AttestationTemplatesController < AdministrateurController
before_action :retrieve_procedure
def show
redirect_to edit_admin_procedure_attestation_template_path(@procedure)
end
def edit
@attestation_template = build_attestation
@attestation_template = build_attestation_template
end
def update
attestation_template = @procedure.draft_attestation_template.find_or_revise!
@procedure.move_attestation_template_to_procedure!
if attestation_template.update(activated_attestation_params)
AttestationTemplate
.where(id: @procedure.revisions.pluck(:attestation_template_id).compact)
.update_all(activated: attestation_template.activated?)
@attestation_template = @procedure.attestation_template
flash.notice = "L'attestation a bien été modifiée"
if @attestation_template.update(activated_attestation_params)
flash.notice = "Le model de lattestation a bien été modifiée"
redirect_to edit_admin_procedure_attestation_template_path(@procedure)
else
flash.alert = attestation_template.errors.full_messages.join('<br>')
end
flash.now.alert = @attestation_template.errors.full_messages
redirect_to edit_admin_procedure_attestation_template_path(@procedure)
render :edit
end
end
def create
attestation_template = build_attestation(activated_attestation_params)
@procedure.move_attestation_template_to_procedure!
if attestation_template.save
if @procedure.publiee? && !@procedure.feature_enabled?(:procedure_revisions)
# If revisions support is not enabled and procedure is published
# attach the same attestation template to published revision.
@procedure.published_revision.update(attestation_template: attestation_template)
end
flash.notice = "L'attestation a bien été sauvegardée"
@attestation_template = build_attestation_template(activated_attestation_params)
if @attestation_template.save
flash.notice = "Le model de lattestation a bien été enregistrée"
redirect_to edit_admin_procedure_attestation_template_path(@procedure)
else
flash.alert = attestation_template.errors.full_messages.join('<br>')
end
flash.now.alert = @attestation_template.errors.full_messages
redirect_to edit_admin_procedure_attestation_template_path(@procedure)
render :edit
end
end
def preview
@attestation = build_attestation.render_attributes_for({})
@attestation = build_attestation_template.render_attributes_for({})
render 'administrateurs/attestation_templates/show', formats: [:pdf]
end
private
def build_attestation(attributes = {})
attestation_template = @procedure.draft_attestation_template || @procedure.draft_revision.build_attestation_template
def build_attestation_template(attributes = {})
attestation_template = @procedure.attestation_template || @procedure.build_attestation_template
attestation_template.attributes = attributes
attestation_template
end

View file

@ -157,7 +157,7 @@ module Types
end
def attestation
if object.attestation_activated?
if object.termine? && object.attestation_template&.activated?
Loaders::Association.for(object.class, attestation: { pdf_attachment: :blob })
.load(object)
.then { |attestation| attestation&.pdf }

View file

@ -15,11 +15,14 @@ class AttestationTemplate < ApplicationRecord
include ActionView::Helpers::NumberHelper
include TagsSubstitutionConcern
belongs_to :procedure, inverse_of: :attestation_template
has_many :revisions, class_name: 'ProcedureRevision', inverse_of: :attestation_template, dependent: :nullify
has_one_attached :logo
has_one_attached :signature
validates :title, tags: true, if: -> { procedure.present? }
validates :body, tags: true, if: -> { procedure.present? }
validates :footer, length: { maximum: 190 }
FILE_MAX_SIZE = 1.megabytes
@ -83,25 +86,8 @@ class AttestationTemplate < ApplicationRecord
}
end
def find_or_revise!
if revisions.size > 1 && procedure.feature_enabled?(:procedure_revisions)
# If attestation template belongs to more then one revision
# and procedure has revisions enabled revise attestation template.
attestation_template = dup
attestation_template.save!
procedure.draft_revision.update!(attestation_template: attestation_template)
attestation_template
else
# If procedure has only one revision or revisions are not supported
# apply updates directly to the attestation template.
# If it is a published procedure with revisions disabled,
# draft and published attestation template will be the same.
self
end
end
def procedure
revisions.last&.procedure
super || revisions.last&.procedure
end
def logo_checksum

View file

@ -29,7 +29,7 @@ module DossierRebaseConcern
end
def accepted_en_construction_change?(change)
if change[:model] == :attestation_template || change[:op] == :move || change[:op] == :remove
if change[:op] == :move || change[:op] == :remove
true
elsif change[:op] == :update
case change[:attribute]
@ -46,7 +46,7 @@ module DossierRebaseConcern
end
def accepted_en_instruction_change?(change)
change[:model] == :attestation_template
false
end
def rebase

View file

@ -135,8 +135,8 @@ class Dossier < ApplicationRecord
has_one :france_connect_information, through: :user
has_one :attestation_template, through: :revision
has_one :procedure, through: :revision
has_one :attestation_template, through: :procedure
has_many :types_de_champ, through: :revision, source: :types_de_champ_public
has_many :types_de_champ_private, through: :revision
@ -375,7 +375,7 @@ class Dossier < ApplicationRecord
.where.not(user: users_who_submitted)
end
scope :for_api_v2, -> { includes(revision: [:attestation_template, procedure: [:administrateurs]], etablissement: [], individual: [], traitement: []) }
scope :for_api_v2, -> { includes(:attestation_template, revision: [procedure: [:administrateurs]], etablissement: [], individual: [], traitement: []) }
scope :with_notifications, -> do
joins(:follows)
@ -748,17 +748,21 @@ class Dossier < ApplicationRecord
{ lon: lon, lat: lat, zoom: zoom }
end
def active_attestation_template
attestation_template || revision.attestation_template
end
def unspecified_attestation_champs
if attestation_template&.activated?
attestation_template.unspecified_champs_for_dossier(self)
if active_attestation_template&.activated?
active_attestation_template.unspecified_champs_for_dossier(self)
else
[]
end
end
def build_attestation
if attestation_template&.activated?
attestation_template.attestation_for(self)
if active_attestation_template&.activated?
active_attestation_template.attestation_for(self)
end
end
@ -819,10 +823,6 @@ class Dossier < ApplicationRecord
end
end
def attestation_activated?
termine? && attestation_template&.activated?
end
def after_passer_en_construction
self.conservation_extension = 0.days
self.depose_at = self.en_construction_at = self.traitements

View file

@ -81,7 +81,6 @@ class Procedure < ApplicationRecord
has_many :published_types_de_champ_private, through: :published_revision, source: :types_de_champ_private
has_one :draft_attestation_template, through: :draft_revision, source: :attestation_template
has_one :published_attestation_template, through: :published_revision, source: :attestation_template
has_one :published_dossier_submitted_message, dependent: :destroy, through: :published_revision, source: :dossier_submitted_message
has_one :draft_dossier_submitted_message, dependent: :destroy, through: :draft_revision, source: :dossier_submitted_message
@ -93,8 +92,7 @@ class Procedure < ApplicationRecord
foreign_key: "replaced_by_procedure_id", dependent: :nullify
has_one :module_api_carto, dependent: :destroy
has_one :legacy_attestation_template, class_name: 'AttestationTemplate', dependent: :destroy
has_many :attestation_templates, through: :revisions, source: :attestation_template
has_one :attestation_template, dependent: :destroy
belongs_to :parent_procedure, class_name: 'Procedure', optional: true
belongs_to :canonical_procedure, class_name: 'Procedure', optional: true
@ -294,6 +292,7 @@ class Procedure < ApplicationRecord
validates_associated :closed_mail, on: :publication
validates_associated :refused_mail, on: :publication
validates_associated :without_continuation_mail, on: :publication
validates_associated :attestation_template, on: :publication, if: -> { attestation_template&.activated? }
FILE_MAX_SIZE = 20.megabytes
validates :notice, content_type: [
@ -473,9 +472,9 @@ class Procedure < ApplicationRecord
populate_champ_stable_ids
include_list = {
attestation_template: [],
draft_revision: {
revision_types_de_champ: [:type_de_champ],
attestation_template: [],
dossier_submitted_message: []
}
}
@ -595,8 +594,11 @@ class Procedure < ApplicationRecord
touch(:whitelisted_at)
end
def attestation_template
published_attestation_template || draft_attestation_template
def move_attestation_template_to_procedure!
if draft_attestation_template.present? && draft_attestation_template != attestation_template
draft_attestation_template.update_column(:procedure_id, id)
reload
end
end
def closed_mail_template_attestation_inconsistency_state

View file

@ -140,14 +140,12 @@ class ProcedureRevision < ApplicationRecord
end
def different_from?(revision)
revision_types_de_champ != revision.revision_types_de_champ ||
attestation_template != revision.attestation_template
revision_types_de_champ != revision.revision_types_de_champ
end
def compare(revision)
changes = []
changes += compare_revision_types_de_champ(revision_types_de_champ, revision.revision_types_de_champ)
changes += compare_attestation_template(attestation_template, revision.attestation_template)
changes
end
@ -240,63 +238,6 @@ class ProcedureRevision < ApplicationRecord
end
end
def compare_attestation_template(from_at, to_at)
changes = []
if from_at.nil? && to_at.present?
changes << {
model: :attestation_template,
op: :add
}
elsif to_at.present?
if from_at.title != to_at.title
changes << {
model: :attestation_template,
op: :update,
attribute: :title,
from: from_at.title,
to: to_at.title
}
end
if from_at.body != to_at.body
changes << {
model: :attestation_template,
op: :update,
attribute: :body,
from: from_at.body,
to: to_at.body
}
end
if from_at.footer != to_at.footer
changes << {
model: :attestation_template,
op: :update,
attribute: :footer,
from: from_at.footer,
to: to_at.footer
}
end
if from_at.logo_checksum != to_at.logo_checksum
changes << {
model: :attestation_template,
op: :update,
attribute: :logo,
from: from_at.logo_filename,
to: to_at.logo_filename
}
end
if from_at.signature_checksum != to_at.signature_checksum
changes << {
model: :attestation_template,
op: :update,
attribute: :signature,
from: from_at.signature_filename,
to: to_at.signature_filename
}
end
end
changes
end
def compare_revision_types_de_champ(from_coordinates, to_coordinates)
if from_coordinates == to_coordinates
[]

View file

@ -8,7 +8,7 @@
.procedure-form#attestation-template-edit
.procedure-form__columns.container
= form_for @attestation_template,
url: url_for({ controller: 'administrateurs/attestation_templates', action: :update, id: @procedure.id }),
url: admin_procedure_attestation_template_path(@procedure),
multipart: true,
html: { class: 'form procedure-form__column--form' } do |f|

View file

@ -1,21 +0,0 @@
- case change[:op]
- when :add
- list.with_item do
= t(:add, scope: [:administrateurs, :revision_changes, :attestation_template])
- when :update
- case change[:attribute]
- when :title
- list.with_item do
= t(:update_title, scope: [:administrateurs, :revision_changes, :attestation_template], to: change[:to])
- when :body
- list.with_item do
= t(:update_body, scope: [:administrateurs, :revision_changes, :attestation_template])
- when :footer
- list.with_item do
= t(:update_footer, scope: [:administrateurs, :revision_changes, :attestation_template])
- when :logo
- list.with_item do
= t(:update_logo, scope: [:administrateurs, :revision_changes, :attestation_template], to: change[:to])
- when :signature
- list.with_item do
= t(:update_signature, scope: [:administrateurs, :revision_changes, :attestation_template], to: change[:to])

View file

@ -2,7 +2,6 @@
- list.with_empty do
= t(:no_changes, scope: [:administrateurs, :revision_changes])
= render partial: 'administrateurs/procedures/revision_change_attestation_template', collection: changes.filter { |change| change[:model] == :attestation_template }, as: :change, locals: { list: list }
= render partial: "administrateurs/procedures/revision_change_type_de_champ", collection: changes.filter { |change| change[:model] == :type_de_champ }, as: :change, locals: { list: list }
- move_changes, move_private_changes = changes.filter { |change| change[:op] == :move }.partition { |change| !change[:private] }
- if move_changes.present?

View file

@ -6,7 +6,7 @@
= form_tag(terminer_instructeur_dossier_path(dossier.procedure, dossier), data: { turbo: true, turbo_confirm: confirm }, method: :post, multipart: true, class: 'form') do
- if title == 'Accepter'
= text_area :dossier, :motivation, class: 'motivation-text-area', placeholder: placeholder, required: false
- if dossier.procedure.attestation_template&.activated?
- if dossier.attestation_template&.activated?
%p.help
Lacceptation du dossier envoie automatiquement
= link_to 'une attestation', apercu_attestation_instructeur_dossier_path(dossier.procedure, dossier), target: '_blank', rel: 'noopener', title: "Voir l'attestation qui sera envoyée à l'usager"

View file

@ -7,7 +7,7 @@ fr:
title:
format: Le titre du modèle de lattestation %{message}
champ_missing: réfère au champ "%{tag}" qui nexiste pas
champ_missing_in_draft_revision: réfère au champ "%{tag}" qui à été supprimé mais la suppression nest pas encore publiée
champ_missing_in_draft_revision: réfère au champ "%{tag}" qui a été supprimé mais la suppression nest pas encore publiée
champ_missing_in_published_revision: réfère au champ "%{tag}" qui nest pas encore publié
champ_missing_in_published_and_draft_revision: réfère au champ "%{tag}" qui a été supprimé
champ_missing_in_previous_revision: réfère au champ "%{tag}" qui nexiste pas sur un des dossiers en cours de traitement

View file

@ -25,6 +25,8 @@ en:
closed_mail: File sorted as accepted notification email
refused_mail: File sorted as refused notification email
without_continuation_mail: File sorted with no further action notification email
attestation_template: Attestation template
draft_revision: The form
errors:
models:
procedure:

View file

@ -25,6 +25,8 @@ fr:
closed_mail: Lemail de notification dacceptation de dossier
refused_mail: Lemail de notification de refus de dossier
without_continuation_mail: Lemail de notification de classement sans suite de dossier
attestation_template: Le modèle d'attestation
draft_revision: Le formulaire
errors:
models:
procedure:

View file

@ -2,13 +2,6 @@ fr:
administrateurs:
revision_changes:
no_changes: Aucune modification
attestation_template:
add: Un model dattestation à été ajouté
update_title: Le titre de lattestation à été modifié. Le nouveau titre est « %{to} »
update_body: Le corps du document de lattestation à été modifié
update_footer: Le pied de page de lattestation à été modifié
update_logo: Le logo de lattestation à été modifié. Le nouveau logo est « %{to} »
update_signature: La signature de lattestation à été modifié. La nouvelle signature est « %{to} »
has_changes: Modifications en cours (appliqué à la prochaine publication)
add: Le champ « %{label} » a été ajouté
remove: Le champ « %{label} » a été supprimé

View file

@ -507,7 +507,7 @@ Rails.application.routes.draw do
get 'preview', on: :member
end
resource :attestation_template, only: [:edit, :update, :create] do
resource :attestation_template, only: [:show, :edit, :update, :create] do
get 'preview', on: :member
end
resource :dossier_submitted_message, only: [:edit, :update, :create]

View file

@ -0,0 +1,38 @@
namespace :after_party do
desc 'Deployment task: assign_attestation_templates_to_procedures'
task assign_attestation_templates_to_procedures: :environment do
puts "Running deploy task 'assign_attestation_templates_to_procedures'"
procedures = Procedure.joins(revisions: :attestation_template, draft_revision: :attestation_template).distinct
progress = ProgressReport.new(procedures.count)
procedures.find_each do |procedure|
draft_revision = procedure.draft_revision
other_revisions = procedure.revisions - [draft_revision]
draft_attestation_template = draft_revision.attestation_template
if draft_attestation_template.present?
other_attestation_templates = other_revisions.map(&:attestation_template).compact - [draft_attestation_template]
AttestationTemplate.transaction do
if other_attestation_templates.present?
AttestationTemplate.where(id: other_attestation_templates.map(&:id)).update_all(procedure_id: nil)
end
AttestationTemplate.where(procedure_id: procedure.id).update_all(procedure_id: nil)
ProcedureRevision
.where(attestation_template_id: draft_attestation_template.id)
.update_all(attestation_template_id: nil)
draft_attestation_template.update_column(:procedure_id, procedure.id)
end
end
progress.inc
end
progress.finish
# Update task as completed. If you remove the line below, the task will
# run with every deploy (or every time you call after_party:run).
AfterParty::TaskRecord
.create version: AfterParty::TaskRecorder.new(__FILE__).timestamp
end
end

View file

@ -1,7 +1,7 @@
describe Administrateurs::AttestationTemplatesController, type: :controller do
let(:admin) { create(:administrateur) }
let(:attestation_template) { build(:attestation_template) }
let(:procedure) { create :procedure, administrateur: admin, attestation_template: attestation_template }
let(:procedure) { create(:procedure, administrateur: admin, attestation_template: attestation_template) }
let(:logo) { fixture_file_upload('spec/fixtures/files/white.png', 'image/png') }
let(:logo2) { fixture_file_upload('spec/fixtures/files/white.png', 'image/png') }
let(:signature) { fixture_file_upload('spec/fixtures/files/black.png', 'image/png') }
@ -36,48 +36,41 @@ describe Administrateurs::AttestationTemplatesController, type: :controller do
params: {
procedure_id: procedure.id
}
procedure.reload
end
context 'if an attestation template exists on the procedure' do
after { procedure.draft_revision.attestation_template&.destroy }
context 'with images' do
let!(:attestation_template) do
create(:attestation_template, attestation_params.merge(logo: logo, signature: signature))
end
let(:attestation_template) { build(:attestation_template, attestation_params.merge(logo: logo, signature: signature)) }
it { expect(assigns(:attestation)).to include(attestation_params) }
it { expect(assigns(:attestation)[:created_at]).to eq(Time.zone.now) }
it { expect(assigns(:attestation)[:logo].download).to eq(logo2.read) }
it { expect(assigns(:attestation)[:signature].download).to eq(signature2.read) }
it do
expect(assigns(:attestation)).to include(attestation_params)
expect(assigns(:attestation)[:created_at]).to eq(Time.zone.now)
expect(assigns(:attestation)[:logo].download).to eq(logo2.read)
expect(assigns(:attestation)[:signature].download).to eq(signature2.read)
end
it_behaves_like 'rendering a PDF successfully'
end
context 'without images' do
let!(:attestation_template) do
create(:attestation_template, attestation_params)
end
let(:attestation_template) { build(:attestation_template, attestation_params) }
it { expect(assigns(:attestation)).to include(attestation_params) }
it { expect(assigns(:attestation)[:created_at]).to eq(Time.zone.now) }
it { expect(assigns(:attestation)[:logo]).to eq(nil) }
it { expect(assigns(:attestation)[:signature]).to eq(nil) }
it do
expect(assigns(:attestation)).to include(attestation_params)
expect(assigns(:attestation)[:created_at]).to eq(Time.zone.now)
expect(assigns(:attestation)[:logo]).to eq(nil)
expect(assigns(:attestation)[:signature]).to eq(nil)
end
it_behaves_like 'rendering a PDF successfully'
end
context 'with empty footer' do
let!(:attestation_template) do
create(:attestation_template, { title: 't', body: 'b', footer: nil })
end
let(:attestation_template) { build(:attestation_template, { title: 't', body: 'b', footer: nil }) }
it_behaves_like 'rendering a PDF successfully'
end
context 'with large footer' do
let!(:attestation_params) do
create(:attestation_template, { title: 't', body: 'b', footer: ' ' * 190 })
end
let(:attestation_params) { build(:attestation_template, { title: 't', body: 'b', footer: ' ' * 190 }) }
it_behaves_like 'rendering a PDF successfully'
end
@ -94,9 +87,12 @@ describe Administrateurs::AttestationTemplatesController, type: :controller do
context 'if an attestation template does not exist on the procedure' do
let(:attestation_template) { nil }
it { expect(subject.status).to eq(200) }
it { expect(assigns(:attestation_template).id).to be_nil }
it { expect(assigns(:attestation_template)).to be_an_instance_of(AttestationTemplate) }
it do
expect(subject.status).to eq(200)
expect(assigns(:attestation_template).id).to be_nil
expect(assigns(:attestation_template)).to be_an_instance_of(AttestationTemplate)
end
end
end
@ -111,17 +107,16 @@ describe Administrateurs::AttestationTemplatesController, type: :controller do
procedure_id: procedure.id,
attestation_template: attestation_params.merge(logo: logo, signature: signature)
}
procedure.reload
end
it { expect(procedure.draft_attestation_template).to have_attributes(attestation_params) }
it { expect(procedure.draft_attestation_template.activated).to be true }
it { expect(procedure.draft_attestation_template.logo.download).to eq(logo2.read) }
it { expect(procedure.draft_attestation_template.signature.download).to eq(signature2.read) }
it { expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure) }
it { expect(flash.notice).to eq("L'attestation a bien été sauvegardée") }
after { procedure.draft_attestation_template.destroy }
it do
expect(procedure.attestation_template).to have_attributes(attestation_params)
expect(procedure.attestation_template.activated).to be true
expect(procedure.attestation_template.logo.download).to eq(logo2.read)
expect(procedure.attestation_template.signature.download).to eq(signature2.read)
expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure)
expect(flash.notice).to eq("Le model de lattestation a bien été enregistrée")
end
end
context 'when something wrong happens in the attestation template creation' do
@ -134,16 +129,16 @@ describe Administrateurs::AttestationTemplatesController, type: :controller do
procedure_id: procedure.id,
attestation_template: attestation_params
}
procedure.reload
end
it { expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure) }
it { expect(flash.alert).to be_present }
it { expect(procedure.draft_attestation_template).to be nil }
it do
expect(flash.alert).to be_present
expect(procedure.draft_attestation_template).to be nil
end
end
context 'when procedure is published' do
let(:procedure) { create(:procedure, :published, administrateur: admin, attestation_template: attestation_template) }
let(:procedure) { create(:procedure, :published, administrateur: admin) }
let(:attestation_template) { nil }
let(:attestation_params) { { title: 't', body: 'b', footer: '', activated: true } }
let(:revisions_enabled) { false }
@ -158,23 +153,11 @@ describe Administrateurs::AttestationTemplatesController, type: :controller do
procedure_id: procedure.id,
attestation_template: attestation_params
}
procedure.reload
end
context 'and revisions are not activated' do
it do
expect(procedure.draft_attestation_template).to eq(procedure.published_attestation_template)
expect(procedure.draft_attestation_template.title).to eq('t')
end
end
context 'and revisions are activated' do
let(:revisions_enabled) { true }
it do
expect(procedure.draft_attestation_template).not_to eq(procedure.published_attestation_template)
expect(procedure.draft_attestation_template.title).to eq('t')
expect(procedure.published_attestation_template).to be_nil
end
it do
expect(procedure.attestation_template).to eq(procedure.attestation_template)
expect(procedure.attestation_template.title).to eq('t')
end
end
end
@ -190,69 +173,93 @@ describe Administrateurs::AttestationTemplatesController, type: :controller do
procedure_id: procedure.id,
attestation_template: attestation_params_with_images
}
procedure.reload
end
it { expect(procedure.draft_attestation_template).to have_attributes(attestation_params) }
it { expect(procedure.draft_attestation_template.logo.download).to eq(logo2.read) }
it { expect(procedure.draft_attestation_template.signature.download).to eq(signature2.read) }
it { expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure) }
it { expect(flash.notice).to eq("L'attestation a bien été modifiée") }
after { procedure.draft_attestation_template&.destroy }
end
context 'when something wrong happens in the attestation template creation' do
before do
expect_any_instance_of(AttestationTemplate).to receive(:update).and_return(false)
expect_any_instance_of(AttestationTemplate).to receive(:errors)
.and_return(double(full_messages: ['nop']))
patch :update,
params: {
procedure_id: procedure.id,
attestation_template: attestation_params_with_images
}
procedure.reload
it do
expect(procedure.attestation_template).to have_attributes(attestation_params)
expect(procedure.attestation_template.logo.download).to eq(logo2.read)
expect(procedure.attestation_template.signature.download).to eq(signature2.read)
expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure)
expect(flash.notice).to eq("Le model de lattestation a bien été modifiée")
end
it { expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure) }
it { expect(flash.alert).to eq('nop') }
end
context 'when procedure is published' do
let(:procedure) { create(:procedure, :published, administrateur: admin, attestation_template: attestation_template) }
let(:attestation_template) { create(:attestation_template, title: 'a') }
let(:attestation_params) { { title: 't', body: 'b', footer: '', activated: true } }
let(:revisions_enabled) { false }
let(:procedure) { create(:procedure, :with_type_de_champ, types_de_champ_count: 3, administrateur: admin, attestation_template: attestation_template) }
let(:dossier) {}
let(:attestation_template) { build(:attestation_template, title: 'a') }
let(:attestation_params) do
{
title: title,
body: body,
footer: '',
activated: true
}
end
let(:type_de_champ) { procedure.draft_revision.types_de_champ_public[0] }
let(:removed_type_de_champ) { procedure.draft_revision.types_de_champ_public[1] }
let(:removed_and_published_type_de_champ) { procedure.draft_revision.types_de_champ_public[2] }
let(:new_type_de_champ) { procedure.draft_revision.types_de_champ_public.find_by(libelle: 'new type de champ') }
let(:draft_type_de_champ) { procedure.draft_revision.types_de_champ_public.find_by(libelle: 'draft type de champ') }
let(:title) { 'title --numéro du dossier--' }
let(:body) { "body --#{type_de_champ.libelle}-- et --#{new_type_de_champ.libelle}--" }
before do
if revisions_enabled
Flipper.enable(:procedure_revisions, procedure)
end
procedure.publish!
procedure.reload
procedure.draft_revision.remove_type_de_champ(removed_and_published_type_de_champ.stable_id)
procedure.draft_revision.add_type_de_champ(libelle: 'new type de champ', type_champ: 'text')
procedure.publish_revision!
procedure.reload
procedure.draft_revision.remove_type_de_champ(removed_type_de_champ.stable_id)
procedure.draft_revision.add_type_de_champ(libelle: 'draft type de champ', type_champ: 'text')
dossier
patch :update,
params: {
procedure_id: procedure.id,
attestation_template: attestation_params
}
procedure.reload
end
context 'and revisions are not activated' do
context 'normal' do
it do
expect(procedure.draft_attestation_template).to eq(procedure.published_attestation_template)
expect(procedure.draft_attestation_template.title).to eq('t')
expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure)
expect(procedure.attestation_template.title).to eq(title)
expect(procedure.attestation_template.body).to eq(body)
end
end
context 'and revisions are activated' do
let(:revisions_enabled) { true }
it do
expect(procedure.draft_attestation_template).not_to eq(procedure.published_attestation_template)
expect(procedure.draft_attestation_template.title).to eq('t')
expect(procedure.published_attestation_template.title).to eq('a')
end
context 'with invalid tag' do
let(:body) { 'body --yolo--' }
it { expect(flash.alert).to eq(['Le contenu du modèle de lattestation réfère au champ "yolo" qui nexiste pas']) }
end
context 'with removed champ' do
let(:body) { "body --#{removed_type_de_champ.libelle}--" }
it { expect(flash.alert).to eq(["Le contenu du modèle de lattestation réfère au champ \"#{removed_type_de_champ.libelle}\" qui a été supprimé mais la suppression nest pas encore publiée"]) }
end
context 'with removed and published' do
let(:body) { "body --#{removed_and_published_type_de_champ.libelle}--" }
it { expect(flash.alert).to eq(["Le contenu du modèle de lattestation réfère au champ \"#{removed_and_published_type_de_champ.libelle}\" qui a été supprimé"]) }
end
context 'with new champ missing on dossier submitted on previous revision' do
let(:dossier) { create(:dossier, :en_construction, procedure: procedure, revision: procedure.revisions.first) }
let(:body) { "body --#{new_type_de_champ.libelle}--" }
it { expect(flash.alert).to eq(["Le contenu du modèle de lattestation réfère au champ \"#{new_type_de_champ.libelle}\" qui nexiste pas sur un des dossiers en cours de traitement"]) }
end
context 'with champ on draft' do
let(:body) { "body --#{draft_type_de_champ.libelle}--" }
it { expect(flash.alert).to eq(["Le contenu du modèle de lattestation réfère au champ \"#{draft_type_de_champ.libelle}\" qui nest pas encore publié"]) }
end
end
end

View file

@ -4,6 +4,7 @@ FactoryBot.define do
body { 'body' }
footer { 'footer' }
activated { true }
association :procedure
end
trait :with_files do

View file

@ -210,8 +210,8 @@ FactoryBot.define do
trait :with_attestation do
after(:build) do |dossier, _evaluator|
dossier.revision.attestation_template ||= build(:attestation_template)
dossier.association(:attestation_template).target = dossier.revision.attestation_template
dossier.procedure.attestation_template ||= build(:attestation_template)
dossier.association(:attestation_template).target = dossier.procedure.attestation_template
dossier.attestation = dossier.build_attestation
end
end

View file

@ -23,7 +23,6 @@ FactoryBot.define do
types_de_champ_public { [] }
types_de_champ_private { [] }
updated_at { nil }
attestation_template { nil }
dossier_submitted_message { nil }
end
@ -32,7 +31,7 @@ FactoryBot.define do
raise "use types_de_champ_public instead of types_de_champ"
end
initial_revision = build(:procedure_revision, procedure: procedure, attestation_template: evaluator.attestation_template, dossier_submitted_message: evaluator.dossier_submitted_message)
initial_revision = build(:procedure_revision, procedure: procedure, dossier_submitted_message: evaluator.dossier_submitted_message)
if evaluator.types_de_champ_public.present?
if !evaluator.types_de_champ_public.first.is_a?(Hash)

View file

@ -9,7 +9,6 @@ FactoryBot.define do
from_revision = evaluator.from_original
revision.procedure = from_revision.procedure
revision.attestation_template_id = from_revision.attestation_template_id
revision.dossier_submitted_message_id = from_revision.dossier_submitted_message_id
coordinate_map = {}

View file

@ -1,22 +0,0 @@
describe '20220112184331_revise_attestation_templates' do
let(:rake_task) { Rake::Task['after_party:revise_attestation_templates'] }
let(:procedure) { create(:procedure) }
let(:attestation_template) { create(:attestation_template, procedure_id: procedure.id) }
subject(:run_task) do
attestation_template
rake_task.invoke
attestation_template.reload
end
after { rake_task.reenable }
describe 'revise_attestation_templates' do
it 'attaches the attestation_template to the latest revision (without removing the link between attestation_template and procedure for now)' do
expect(procedure.revisions.first.attestation_template_id).to be_nil
run_task
expect(attestation_template.procedure_id).to eq(procedure.id)
expect(procedure.revisions.first.attestation_template_id).to eq(attestation_template.id)
end
end
end

View file

@ -1,51 +0,0 @@
describe '20220211090402_reassign_redundant_attestation_templates' do
let(:rake_task) { Rake::Task['after_party:reassign_redundant_attestation_templates'] }
let(:procedure) { create(:procedure, :published) }
let(:procedure_with_revisions) { create(:procedure, :published) }
before do
procedure.published_revision.update(attestation_template: create(:attestation_template))
procedure.draft_revision.update(attestation_template: procedure.published_attestation_template.dup)
Flipper.enable(:procedure_revisions, procedure_with_revisions)
procedure_with_revisions.published_revision.update(attestation_template: create(:attestation_template))
procedure_with_revisions.draft_revision.update(attestation_template: procedure_with_revisions.published_attestation_template.dup)
end
subject(:run_task) do
rake_task.invoke
procedure.reload
procedure_with_revisions.reload
end
after { rake_task.reenable }
describe 'reassign_redundant_attestation_templates' do
it 'reassign draft attestation template as published attestation template on procedures without revisions' do
expect(procedure.published_attestation_template).not_to be_nil
expect(procedure.draft_attestation_template).not_to be_nil
expect(procedure.draft_attestation_template).not_to eq(procedure.published_attestation_template)
expect(procedure_with_revisions.published_attestation_template).not_to be_nil
expect(procedure_with_revisions.draft_attestation_template).not_to be_nil
expect(procedure_with_revisions.draft_attestation_template).not_to eq(procedure_with_revisions.published_attestation_template)
orphans = AttestationTemplate.where(procedure_id: nil).left_outer_joins(:revisions).filter { |a| a.revisions.empty? }
expect(orphans).to eq([])
to_be_orphan = procedure.published_attestation_template
run_task
expect(procedure.published_attestation_template).not_to be_nil
expect(procedure.draft_attestation_template).not_to be_nil
expect(procedure.draft_attestation_template).to eq(procedure.published_attestation_template)
expect(procedure_with_revisions.published_attestation_template).not_to be_nil
expect(procedure_with_revisions.draft_attestation_template).not_to be_nil
expect(procedure_with_revisions.draft_attestation_template).not_to eq(procedure_with_revisions.published_attestation_template)
orphans = AttestationTemplate.where(procedure_id: nil).left_outer_joins(:revisions).filter { |a| a.revisions.empty? }
expect(orphans).to eq([to_be_orphan])
end
end
end

View file

@ -0,0 +1,33 @@
describe '20221108114545_assign_attestation_templates_to_procedures' do
let(:rake_task) { Rake::Task['after_party:assign_attestation_templates_to_procedures'] }
let(:procedure) { create(:procedure, :published) }
let(:attestation_template) { create(:attestation_template) }
let(:attestation_template_old) { create(:attestation_template, procedure: procedure) }
let(:procedure2) { create(:procedure, :published) }
let(:attestation_template2) { create(:attestation_template) }
subject(:run_task) do
rake_task.invoke
end
before do
procedure.draft_revision.add_type_de_champ(type_champ: :integer_number, libelle: 'l1')
procedure.publish_revision!
procedure.draft_revision.update!(attestation_template: attestation_template)
procedure.published_revision.update!(attestation_template: attestation_template)
procedure.revisions.first.update!(attestation_template: attestation_template_old)
procedure2.draft_revision.update!(attestation_template: attestation_template2)
procedure2.published_revision.update!(attestation_template: attestation_template2)
end
after { rake_task.reenable }
it "assigns attestation template to procedure" do
expect(procedure.attestation_template).to eq(attestation_template_old)
expect(procedure2.attestation_template).to be_nil
run_task
expect(procedure.reload.attestation_template).to eq(attestation_template)
expect(attestation_template_old.reload.procedure_id).to be_nil
expect(procedure2.reload.attestation_template).to eq(attestation_template2)
end
end

View file

@ -70,19 +70,6 @@ describe Dossier do
expect(dossier.can_rebase?).to be_truthy
end
end
context 'with attestation template changes' do
before do
attestation_template.update(title: "Test")
procedure.publish_revision!
dossier.reload
end
it 'should be true' do
expect(dossier.pending_changes).not_to be_empty
expect(dossier.can_rebase?).to be_truthy
end
end
end
context 'en_instruction' do
@ -123,19 +110,6 @@ describe Dossier do
end
end
context 'with attestation template changes' do
before do
attestation_template.update(title: "Test")
procedure.publish_revision!
dossier.reload
end
it 'should be true' do
expect(dossier.pending_changes).not_to be_empty
expect(dossier.can_rebase?).to be_truthy
end
end
context 'with type de champ made optional' do
before do
procedure.draft_revision.find_and_ensure_exclusive_use(mandatory_type_de_champ.stable_id).update(mandatory: false)

View file

@ -775,20 +775,20 @@ describe Dossier do
end
context 'when the dossier is in en_instruction state ' do
let!(:dossier) { create(:dossier, procedure: procedure, state: Dossier.states.fetch(:en_instruction)) }
let!(:dossier) { create(:dossier, :en_instruction, procedure: procedure) }
context 'when the procedure has no attestation' do
it { expect(dossier.attestation).to be_nil }
end
context 'when the procedure has an unactivated attestation' do
let(:attestation_template) { AttestationTemplate.new(activated: false) }
let(:attestation_template) { build(:attestation_template, activated: false) }
it { expect(dossier.attestation).to be_nil }
end
context 'when the procedure attached has an activated attestation' do
let(:attestation_template) { AttestationTemplate.new(activated: true) }
let(:attestation_template) { build(:attestation_template, activated: true) }
it { expect(dossier.attestation).not_to be_nil }
end

View file

@ -904,7 +904,7 @@ describe Procedure do
create(
:procedure,
:published,
attestation_template: create(:attestation_template),
attestation_template: build(:attestation_template),
dossier_submitted_message: create(:dossier_submitted_message),
types_de_champ_public: [{ type: :text, libelle: 'published tdc' }]
)
@ -913,7 +913,7 @@ describe Procedure do
it "should reset draft revision" do
procedure.draft_revision.add_type_de_champ(tdc_attributes)
previous_draft_revision = procedure.draft_revision
previous_attestation_template = previous_draft_revision.attestation_template
previous_attestation_template = procedure.attestation_template
previous_dossier_submitted_message = previous_draft_revision.dossier_submitted_message
expect(procedure.draft_changed?).to be_truthy
@ -921,7 +921,7 @@ describe Procedure do
expect(procedure.draft_changed?).to be_falsey
expect(procedure.draft_revision).not_to eq(previous_draft_revision)
expect { previous_draft_revision.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect(procedure.draft_revision.attestation_template).to eq(previous_attestation_template)
expect(procedure.attestation_template).to eq(previous_attestation_template)
expect(procedure.draft_revision.dossier_submitted_message).to eq(previous_dossier_submitted_message)
end

View file

@ -33,7 +33,7 @@ describe 'As an administrateur, I want to manage the procedures attestation',
fill_in "Corps du document", with: 'BOOM'
find('.toggle-switch-control').click
click_on 'Enregistrer'
page.find(".alert-success", text: "L'attestation a bien été sauvegardée")
page.find(".alert-success", text: "Le model de lattestation a bien été enregistrée")
# check attestation
visit admin_procedure_path(procedure)
@ -49,7 +49,7 @@ describe 'As an administrateur, I want to manage the procedures attestation',
find_attestation_card.click
find('.toggle-switch-control').click
click_on 'Enregistrer'
page.find(".alert-success", text: "L'attestation a bien été modifiée")
page.find(".alert-success", text: "Le model de lattestation a bien été modifiée")
# check attestation is now disabled
visit admin_procedure_path(procedure)