Merge pull request #6452 from betagouv/main

This commit is contained in:
Pierre de La Morinerie 2021-09-07 11:20:56 -05:00 committed by GitHub
commit 45845b6233
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 165 additions and 45 deletions

View file

@ -151,15 +151,15 @@ module Instructeurs
case params[:process_action]
when "refuser"
target_state = :refuse
dossier.refuser!(current_instructeur, motivation, justificatif)
dossier.refuser!(current_instructeur, motivation, justificatif: justificatif)
flash.notice = "Dossier considéré comme refusé."
when "classer_sans_suite"
target_state = :sans_suite
dossier.classer_sans_suite!(current_instructeur, motivation, justificatif)
dossier.classer_sans_suite!(current_instructeur, motivation, justificatif: justificatif)
flash.notice = "Dossier considéré comme sans suite."
when "accepter"
target_state = :accepte
dossier.accepter!(current_instructeur, motivation, justificatif)
dossier.accepter!(current_instructeur, motivation, justificatif: justificatif)
flash.notice = "Dossier traité avec succès."
end
rescue AASM::InvalidTransition => e

View file

@ -8,12 +8,13 @@ module Mutations
argument :instructeur_id, ID, "Instructeur qui prend la décision sur le dossier.", required: true, loads: Types::ProfileType
argument :motivation, String, required: false
argument :justificatif, ID, required: false
argument :disable_notification, Boolean, "Désactiver lenvoi de lemail de notification après lopération", required: false, default_value: false
field :dossier, Types::DossierType, null: true
field :errors, [Types::ValidationErrorType], null: true
def resolve(dossier:, instructeur:, motivation: nil, justificatif: nil)
dossier.accepter!(instructeur, motivation, justificatif)
def resolve(dossier:, instructeur:, motivation: nil, justificatif: nil, disable_notification:)
dossier.accepter!(instructeur, motivation, justificatif: justificatif, disable_notification: disable_notification)
{ dossier: dossier }
end

View file

@ -8,12 +8,13 @@ module Mutations
argument :instructeur_id, ID, "Instructeur qui prend la décision sur le dossier.", required: true, loads: Types::ProfileType
argument :motivation, String, required: true
argument :justificatif, ID, required: false
argument :disable_notification, Boolean, "Désactiver lenvoi de lemail de notification après lopération", required: false, default_value: false
field :dossier, Types::DossierType, null: true
field :errors, [Types::ValidationErrorType], null: true
def resolve(dossier:, instructeur:, motivation:, justificatif: nil)
dossier.classer_sans_suite!(instructeur, motivation, justificatif)
def resolve(dossier:, instructeur:, motivation:, justificatif: nil, disable_notification:)
dossier.classer_sans_suite!(instructeur, motivation, justificatif: justificatif, disable_notification: disable_notification)
{ dossier: dossier }
end

View file

@ -6,17 +6,18 @@ module Mutations
argument :dossier_id, ID, "Dossier ID", required: true, loads: Types::DossierType
argument :instructeur_id, ID, "Instructeur qui prend la décision sur le dossier.", required: true, loads: Types::ProfileType
argument :disable_notification, Boolean, "Désactiver lenvoi de lemail de notification après lopération", required: false, default_value: false
field :dossier, Types::DossierType, null: true
field :errors, [Types::ValidationErrorType], null: true
def resolve(dossier:, instructeur:)
dossier.passer_en_instruction!(instructeur)
def resolve(dossier:, instructeur:, disable_notification:)
dossier.passer_en_instruction!(instructeur, disable_notification: disable_notification)
{ dossier: dossier }
end
def authorized?(dossier:, instructeur:)
def authorized?(dossier:, instructeur:, **args)
if !dossier.en_construction?
return false, { errors: ["Le dossier est déjà #{dossier_display_state(dossier, lower: true)}"] }
end

View file

@ -8,12 +8,13 @@ module Mutations
argument :instructeur_id, ID, "Instructeur qui prend la décision sur le dossier.", required: true, loads: Types::ProfileType
argument :motivation, String, required: true
argument :justificatif, ID, required: false
argument :disable_notification, Boolean, "Désactiver lenvoi de lemail de notification après lopération", required: false, default_value: false
field :dossier, Types::DossierType, null: true
field :errors, [Types::ValidationErrorType], null: true
def resolve(dossier:, instructeur:, motivation:, justificatif: nil)
dossier.refuser!(instructeur, motivation, justificatif)
def resolve(dossier:, instructeur:, motivation:, justificatif: nil, disable_notification:)
dossier.refuser!(instructeur, motivation, justificatif: justificatif, disable_notification: disable_notification)
{ dossier: dossier }
end

View file

@ -748,6 +748,11 @@ input DossierAccepterInput {
"""
clientMutationId: String
"""
Désactiver lenvoi de lemail de notification après lopération
"""
disableNotification: Boolean = false
"""
Dossier ID
"""
@ -846,6 +851,11 @@ input DossierClasserSansSuiteInput {
"""
clientMutationId: String
"""
Désactiver lenvoi de lemail de notification après lopération
"""
disableNotification: Boolean = false
"""
Dossier ID
"""
@ -1164,6 +1174,11 @@ input DossierPasserEnInstructionInput {
"""
clientMutationId: String
"""
Désactiver lenvoi de lemail de notification après lopération
"""
disableNotification: Boolean = false
"""
Dossier ID
"""
@ -1196,6 +1211,11 @@ input DossierRefuserInput {
"""
clientMutationId: String
"""
Désactiver lenvoi de lemail de notification après lopération
"""
disableNotification: Boolean = false
"""
Dossier ID
"""

View file

@ -30,6 +30,7 @@ class BillSignature < ApplicationRecord
io: StringIO.new(operations_bill_json),
filename: "demarches-simplifiees-operations-#{day.to_date.iso8601}.json",
content_type: 'application/json',
# we don't want to run virus scanner on this file
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
)
@ -52,7 +53,9 @@ class BillSignature < ApplicationRecord
self.signature.attach(
io: StringIO.new(signature),
filename: "demarches-simplifiees-signature-#{day.to_date.iso8601}.der",
content_type: 'application/x-x509-ca-cert'
content_type: 'application/x-x509-ca-cert',
# we don't want to run virus scanner on this file
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
)
end

View file

@ -20,7 +20,7 @@
class Champs::PaysChamp < Champs::TextChamp
def localized_value
if external_id
I18nData.countries(I18n.locale)[external_id]
I18nData.countries(I18n.locale)[external_id].to_s
else
value.present? ? value.to_s : ''
end

View file

@ -374,7 +374,6 @@ class Dossier < ApplicationRecord
before_save :build_default_champs, if: Proc.new { revision_id_was.nil? }
before_save :update_search_terms
after_save :send_dossier_en_instruction
after_save :send_web_hook
after_create_commit :send_draft_notification_email
@ -676,10 +675,13 @@ class Dossier < ApplicationRecord
update!(en_construction_at: Time.zone.now) if self.en_construction_at.nil?
end
def after_passer_en_instruction(instructeur)
def after_passer_en_instruction(instructeur, disable_notification: false)
instructeur.follow(self)
update!(en_instruction_at: Time.zone.now) if self.en_instruction_at.nil?
if !procedure.declarative_accepte? && !disable_notification
NotificationMailer.send_en_instruction_notification(self).deliver_later
end
log_dossier_operation(instructeur, :passer_en_instruction)
end
@ -695,17 +697,19 @@ class Dossier < ApplicationRecord
log_dossier_operation(instructeur, :repasser_en_construction)
end
def after_repasser_en_instruction(instructeur)
def after_repasser_en_instruction(instructeur, disable_notification: false)
self.archived = false
self.en_instruction_at = Time.zone.now
attestation&.destroy
save!
DossierMailer.notify_revert_to_instruction(self).deliver_later
if !disable_notification
DossierMailer.notify_revert_to_instruction(self).deliver_later
end
log_dossier_operation(instructeur, :repasser_en_instruction)
end
def after_accepter(instructeur, motivation, justificatif = nil)
def after_accepter(instructeur, motivation, justificatif: nil, disable_notification: false)
self.traitements.accepter(motivation: motivation, instructeur: instructeur)
if justificatif
@ -718,7 +722,9 @@ class Dossier < ApplicationRecord
save!
remove_titres_identite!
NotificationMailer.send_accepte_notification(self).deliver_later
if !disable_notification
NotificationMailer.send_accepte_notification(self).deliver_later
end
send_dossier_decision_to_experts(self)
log_dossier_operation(instructeur, :accepter, self)
end
@ -738,7 +744,7 @@ class Dossier < ApplicationRecord
log_automatic_dossier_operation(:accepter, self)
end
def after_refuser(instructeur, motivation, justificatif = nil)
def after_refuser(instructeur, motivation, justificatif: nil, disable_notification: false)
self.traitements.refuser(motivation: motivation, instructeur: instructeur)
if justificatif
@ -747,12 +753,14 @@ class Dossier < ApplicationRecord
save!
remove_titres_identite!
NotificationMailer.send_refuse_notification(self).deliver_later
if !disable_notification
NotificationMailer.send_refuse_notification(self).deliver_later
end
send_dossier_decision_to_experts(self)
log_dossier_operation(instructeur, :refuser, self)
end
def after_classer_sans_suite(instructeur, motivation, justificatif = nil)
def after_classer_sans_suite(instructeur, motivation, justificatif: nil, disable_notification: false)
self.traitements.classer_sans_suite(motivation: motivation, instructeur: instructeur)
if justificatif
@ -761,7 +769,9 @@ class Dossier < ApplicationRecord
save!
remove_titres_identite!
NotificationMailer.send_sans_suite_notification(self).deliver_later
if !disable_notification
NotificationMailer.send_sans_suite_notification(self).deliver_later
end
send_dossier_decision_to_experts(self)
log_dossier_operation(instructeur, :classer_sans_suite, self)
end
@ -968,12 +978,6 @@ class Dossier < ApplicationRecord
end
end
def send_dossier_en_instruction
if saved_change_to_state? && en_instruction? && !procedure.declarative_accepte?
NotificationMailer.send_en_instruction_notification(self).deliver_later
end
end
def send_draft_notification_email
if brouillon? && !procedure.declarative?
DossierMailer.notify_new_draft(self).deliver_later

View file

@ -176,6 +176,7 @@ class Etablissement < ApplicationRecord
attestation.attach(
io: StringIO.new(response.body),
filename: filename,
# we don't want to run virus scanner on this file
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
)
end

View file

@ -40,7 +40,12 @@ class ProcedureArchiveService
end
end
archive.file.attach(io: File.open(tmp_file), filename: archive.filename(@procedure))
archive.file.attach(
io: File.open(tmp_file),
filename: archive.filename(@procedure),
# we don't want to run virus scanner on this file
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
)
tmp_file.delete
archive.make_available!
InstructeurMailer.send_archive(instructeur, @procedure, archive).deliver_later

View file

@ -34,7 +34,9 @@ describe API::V2::GraphqlController do
filename: file.original_filename,
byte_size: file.size,
checksum: compute_checksum_in_chunks(file),
content_type: file.content_type
content_type: file.content_type,
# we don't want to run virus scanner on this file
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
}
end
let(:blob) do
@ -902,11 +904,13 @@ describe API::V2::GraphqlController do
describe 'dossierPasserEnInstruction' do
let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) }
let(:instructeur_id) { instructeur.to_typed_id }
let(:disable_notification) { false }
let(:query) do
"mutation {
dossierPasserEnInstruction(input: {
dossierId: \"#{dossier.to_typed_id}\",
instructeurId: \"#{instructeur_id}\"
instructeurId: \"#{instructeur_id}\",
disableNotification: #{disable_notification}
}) {
dossier {
id
@ -932,6 +936,9 @@ describe API::V2::GraphqlController do
},
errors: nil
})
perform_enqueued_jobs
expect(ActionMailer::Base.deliveries.size).to eq(4)
end
end
@ -958,6 +965,25 @@ describe API::V2::GraphqlController do
})
end
end
context 'disable notification' do
let(:disable_notification) { true }
it "should passer en instruction dossier without notification" do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierPasserEnInstruction: {
dossier: {
id: dossier.to_typed_id,
state: "en_instruction",
motivation: nil
},
errors: nil
})
perform_enqueued_jobs
expect(ActionMailer::Base.deliveries.size).to eq(3)
end
end
end
describe 'dossierClasserSansSuite' do

View file

@ -11,7 +11,13 @@ FactoryBot.define do
trait :with_piece_justificative_file do
after(:build) do |champ, _evaluator|
champ.piece_justificative_file.attach(io: StringIO.new("toto"), filename: "toto.txt", content_type: "text/plain")
champ.piece_justificative_file.attach(
io: StringIO.new("toto"),
filename: "toto.txt",
content_type: "text/plain",
# we don't want to run virus scanner on this file
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
)
end
end
@ -143,7 +149,13 @@ FactoryBot.define do
end
after(:build) do |champ, evaluator|
champ.piece_justificative_file.attach(io: StringIO.new("x" * evaluator.size), filename: "toto.txt", content_type: "text/plain")
champ.piece_justificative_file.attach(
io: StringIO.new("x" * evaluator.size),
filename: "toto.txt",
content_type: "text/plain",
# we don't want to run virus scanner on this file
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
)
end
end
@ -151,7 +163,13 @@ FactoryBot.define do
type_de_champ { association :type_de_champ_titre_identite, procedure: dossier.procedure }
after(:build) do |champ, _evaluator|
champ.piece_justificative_file.attach(io: StringIO.new("toto"), filename: "toto.png", content_type: "image/png")
champ.piece_justificative_file.attach(
io: StringIO.new("toto"),
filename: "toto.png",
content_type: "image/png",
# we don't want to run virus scanner on this file
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
)
end
end

View file

@ -205,7 +205,9 @@ FactoryBot.define do
after(:create) do |dossier, _evaluator|
dossier.justificatif_motivation.attach(
io: StringIO.new('Hello World'),
filename: 'hello.txt'
filename: 'hello.txt',
# we don't want to run virus scanner on this file
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
)
end
end

View file

@ -248,7 +248,9 @@ FactoryBot.define do
after(:create) do |procedure, _evaluator|
procedure.notice.attach(
io: StringIO.new('Hello World'),
filename: 'hello.txt'
filename: 'hello.txt',
# we don't want to run virus scanner on this file
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
)
end
end
@ -257,7 +259,9 @@ FactoryBot.define do
after(:create) do |procedure, _evaluator|
procedure.deliberation.attach(
io: StringIO.new('Hello World'),
filename: 'hello.txt'
filename: 'hello.txt',
# we don't want to run virus scanner on this file
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
)
end
end

View file

@ -130,7 +130,13 @@ FactoryBot.define do
type_champ { TypeDeChamp.type_champs.fetch(:piece_justificative) }
after(:build) do |type_de_champ, _evaluator|
type_de_champ.piece_justificative_template.attach(io: StringIO.new("toto"), filename: "toto.txt", content_type: "text/plain")
type_de_champ.piece_justificative_template.attach(
io: StringIO.new("toto"),
filename: "toto.txt",
content_type: "text/plain",
# we don't want to run virus scanner on this file
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
)
end
end
factory :type_de_champ_titre_identite do

View file

@ -320,7 +320,7 @@ describe TagsSubstitutionConcern, type: :model do
Timecop.freeze(Time.zone.local(2004, 5, 6))
dossier.passer_en_instruction!(instructeur)
Timecop.freeze(Time.zone.local(2007, 8, 9))
dossier.accepter!(instructeur, nil, nil)
dossier.accepter!(instructeur, nil)
Timecop.return
end

View file

@ -239,7 +239,7 @@ describe Dossier do
Timecop.freeze(date2)
d.passer_en_instruction!(instructeur)
Timecop.freeze(date3)
d.accepter!(instructeur, "Motivation", nil)
d.accepter!(instructeur, "Motivation")
Timecop.return
d
end
@ -422,7 +422,7 @@ describe Dossier do
let(:dossier) { create(:dossier, :en_instruction, :with_individual) }
before do
dossier.accepter!(instructeur, nil, nil)
dossier.accepter!(instructeur, nil)
dossier.reload
end
@ -435,7 +435,7 @@ describe Dossier do
let(:dossier) { create(:dossier, :en_instruction, :with_individual) }
before do
dossier.refuser!(instructeur, nil, nil)
dossier.refuser!(instructeur, nil)
dossier.reload
end
@ -447,7 +447,7 @@ describe Dossier do
let(:dossier) { create(:dossier, :en_instruction, :with_individual) }
before do
dossier.classer_sans_suite!(instructeur, nil, nil)
dossier.classer_sans_suite!(instructeur, nil)
dossier.reload
end

View file

@ -184,6 +184,33 @@ describe DossierProjectionService do
it { is_expected.to eq('18 a la bonne rue') }
end
context 'for type_de_champ table: type_de_champ pays which needs external_id field' do
let(:table) { 'type_de_champ' }
let(:procedure) { create(:procedure, types_de_champ: [build(:type_de_champ_pays)]) }
let(:dossier) { create(:dossier, procedure: procedure) }
let(:column) { dossier.procedure.types_de_champ.first.stable_id.to_s }
let!(:previous_locale) { I18n.locale }
before { I18n.locale = :fr }
after { I18n.locale = previous_locale }
context 'when external id is set' do
before do
dossier.champs.first.update(external_id: 'GB')
end
it { is_expected.to eq('Royaume-Uni') }
end
context 'when no external id is set' do
before do
dossier.champs.first.update(value: "qu'il est beau mon pays")
end
it { is_expected.to eq("qu'il est beau mon pays") }
end
end
end
end
end