Refactor individual creation (#4670)

Nettoyage de la création des objets `Individual`
This commit is contained in:
Pierre de La Morinerie 2020-01-08 14:20:42 +01:00 committed by GitHub
commit b5c663e01c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 122 additions and 134 deletions

View file

@ -220,27 +220,30 @@ module Users
def new
erase_user_location!
if params[:brouillon]
procedure = Procedure.brouillon.find(params[:procedure_id])
else
procedure = Procedure.publiees.find(params[:procedure_id])
begin
if params[:brouillon]
procedure = Procedure.brouillon.find(params[:procedure_id])
else
procedure = Procedure.publiees.find(params[:procedure_id])
end
rescue ActiveRecord::RecordNotFound
flash.alert = t('errors.messages.procedure_not_found')
return redirect_to url_for dossiers_path
end
dossier = Dossier.create!(groupe_instructeur: procedure.defaut_groupe_instructeur, user: current_user, state: Dossier.states.fetch(:brouillon))
dossier = Dossier.new(
groupe_instructeur: procedure.defaut_groupe_instructeur,
user: current_user,
state: Dossier.states.fetch(:brouillon)
)
dossier.build_default_individual
dossier.save!
if dossier.procedure.for_individual
if current_user.france_connect_information.present?
dossier.update_with_france_connect(current_user.france_connect_information)
end
redirect_to identite_dossier_path(dossier)
else
redirect_to siret_dossier_path(id: dossier.id)
end
rescue ActiveRecord::RecordNotFound
flash.alert = t('errors.messages.procedure_not_found')
redirect_to url_for dossiers_path
end
def dossier_for_help

View file

@ -21,7 +21,7 @@ class Dossier < ApplicationRecord
DRAFT_EXPIRATION = 1.month + 5.days
has_one :etablissement, dependent: :destroy
has_one :individual, dependent: :destroy
has_one :individual, validate: false, dependent: :destroy
has_one :attestation, dependent: :destroy
has_one_attached :justificatif_motivation
@ -207,9 +207,7 @@ class Dossier < ApplicationRecord
delegate :france_connect_information, to: :user
before_validation :update_state_dates, if: -> { state_changed? }
before_save :build_default_champs, if: Proc.new { groupe_instructeur_id_was.nil? }
before_save :build_default_individual, if: Proc.new { procedure.for_individual? }
before_save :update_search_terms
after_save :send_dossier_received
@ -217,6 +215,7 @@ class Dossier < ApplicationRecord
after_create :send_draft_notification_email
validates :user, presence: true
validates :individual, presence: true, if: -> { procedure.for_individual? }
def update_search_terms
self.search_terms = [
@ -239,8 +238,12 @@ class Dossier < ApplicationRecord
end
def build_default_individual
if Individual.where(dossier_id: self.id).count == 0
build_individual
if procedure.for_individual? && individual.blank?
self.individual = if france_connect_information.present?
Individual.from_france_connect(france_connect_information)
else
Individual.new
end
end
end
@ -579,10 +582,6 @@ class Dossier < ApplicationRecord
!PiecesJustificativesService.liste_pieces_justificatives(self).empty? && PiecesJustificativesService.pieces_justificatives_total_size(self) < Dossier::TAILLE_MAX_ZIP
end
def update_with_france_connect(fc_information)
self.individual = Individual.create_from_france_connect(fc_information)
end
def linked_dossiers
Dossier.where(id: champs.filter(&:dossier_link?).map(&:value).compact)
end

View file

@ -9,8 +9,8 @@ class Individual < ApplicationRecord
GENDER_MALE = 'M.'
GENDER_FEMALE = 'Mme'
def self.create_from_france_connect(fc_information)
create!(
def self.from_france_connect(fc_information)
new(
nom: fc_information.family_name,
prenom: fc_information.given_name,
gender: fc_information.gender == 'female' ? GENDER_FEMALE : GENDER_MALE

View file

@ -15,7 +15,7 @@ describe API::V2::GraphqlController do
end
let(:dossier1) { create(:dossier, :en_construction, :for_individual, procedure: procedure, en_construction_at: 1.day.ago) }
let(:dossier2) { create(:dossier, :en_construction, :for_individual, procedure: procedure, en_construction_at: 3.days.ago) }
let!(:dossier_brouillon) { create(:dossier, :for_individual, procedure: procedure) }
let(:dossier_brouillon) { create(:dossier, :for_individual, procedure: procedure) }
let(:dossiers) { [dossier2, dossier1, dossier] }
let(:instructeur) { create(:instructeur, followed_dossiers: dossiers) }
@ -169,71 +169,71 @@ describe API::V2::GraphqlController do
end
context "dossier" do
let(:query) do
"{
dossier(number: #{dossier.id}) {
id
number
state
dateDerniereModification
datePassageEnConstruction
datePassageEnInstruction
dateTraitement
motivation
motivationAttachment {
url
}
usager {
context "with individual" do
let(:query) do
"{
dossier(number: #{dossier.id}) {
id
email
}
demandeur {
id
... on PersonnePhysique {
nom
prenom
civilite
dateDeNaissance
}
}
instructeurs {
id
email
}
messages {
email
body
attachment {
filename
checksum
byteSize
contentType
number
state
dateDerniereModification
datePassageEnConstruction
datePassageEnInstruction
dateTraitement
motivation
motivationAttachment {
url
}
}
avis {
expert {
usager {
id
email
}
question
reponse
dateQuestion
dateReponse
attachment {
url
filename
demandeur {
id
... on PersonnePhysique {
nom
prenom
civilite
dateDeNaissance
}
}
instructeurs {
id
email
}
messages {
email
body
attachment {
filename
checksum
byteSize
contentType
url
}
}
avis {
expert {
email
}
question
reponse
dateQuestion
dateReponse
attachment {
url
filename
}
}
champs {
id
label
stringValue
}
}
champs {
id
label
stringValue
}
}
}"
end
}"
end
context "with individual" do
it "should be returned" do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossier: {

View file

@ -15,9 +15,12 @@ FactoryBot.define do
procedure = create(:procedure, :published, :with_type_de_champ, :with_type_de_champ_private)
end
# Assign the procedure to the dossier through the groupe_instructeur
if dossier.groupe_instructeur.nil?
dossier.groupe_instructeur = procedure.defaut_groupe_instructeur
end
dossier.build_default_individual
end
trait :with_entreprise do

View file

@ -5,6 +5,13 @@ describe Dossier do
let(:user) { create(:user) }
describe 'validations' do
let(:procedure) { create(:procedure, :for_individual) }
subject(:dossier) { create(:dossier, procedure: procedure) }
it { is_expected.to validate_presence_of(:individual) }
end
describe "without_followers scope" do
let!(:dossier) { create(:dossier, :followed, :with_entreprise, user: user) }
let!(:dossier2) { create(:dossier, :with_entreprise, user: user) }
@ -112,56 +119,44 @@ describe Dossier do
end
end
describe '#build_default_champs' do
context 'when dossier is linked to a procedure with type_de_champ_public and private' do
let(:dossier) { create(:dossier, user: user) }
describe '#create' do
let(:procedure) { create(:procedure, :with_type_de_champ, :with_type_de_champ_private) }
let(:dossier) { create(:dossier, procedure: procedure, user: user) }
it 'build all champs needed' do
expect(dossier.champs.count).to eq(1)
it 'builds public and private champs' do
expect(dossier.champs.count).to eq(1)
expect(dossier.champs_private.count).to eq(1)
end
context 'when the dossier belongs to a procedure for individuals' do
let(:procedure) { create(:procedure, :with_type_de_champ, for_individual: true) }
it 'creates a default individual' do
expect(dossier.individual).to be_present
expect(dossier.individual.nom).to be_nil
expect(dossier.individual.prenom).to be_nil
expect(dossier.individual.gender).to be_nil
end
it 'build all champs_private needed' do
expect(dossier.champs_private.count).to eq(1)
context 'and the user signs-in using France Connect' do
let(:france_connect_information) { build(:france_connect_information) }
let(:user) { build(:user, france_connect_information: france_connect_information) }
it 'fills the individual with the informations from France Connect' do
expect(dossier.individual.nom).to eq('DUBOIS')
expect(dossier.individual.prenom).to eq('Angela Claire Louise')
expect(dossier.individual.gender).to eq(Individual::GENDER_FEMALE)
end
end
end
end
describe '#build_default_individual' do
context 'when dossier is linked to a procedure with for_individual attr false' do
let(:dossier) { create(:dossier, user: user) }
context 'when the dossier belongs to a procedure for moral personas' do
let(:procedure) { create(:procedure, :with_type_de_champ, for_individual: false) }
it 'have no object created' do
it 'doesnt create a individual' do
expect(dossier.individual).to be_nil
end
end
context 'when dossier is linked to a procedure with for_individual attr true' do
let(:dossier) { create(:dossier, user: user, procedure: (create :procedure, for_individual: true)) }
it 'have no object created' do
expect(dossier.individual).not_to be_nil
end
end
end
describe '#save' do
subject { build(:dossier, procedure: procedure, user: user) }
let!(:procedure) { create(:procedure) }
context 'when is linked to a procedure' do
it 'creates default champs' do
expect(subject).to receive(:build_default_champs)
subject.save
end
end
context 'when is not linked to a procedure' do
subject { create(:dossier, procedure: nil, user: user) }
it 'does not create default champs' do
expect(subject).not_to receive(:build_default_champs)
subject.update(state: Dossier.states.fetch(:en_construction))
end
end
end
end
@ -1019,18 +1014,6 @@ describe Dossier do
end
end
describe '#update_with_france_connect' do
let(:dossier) { create(:dossier, user: user) }
let(:user_info) { create(:france_connect_information) }
it {
dossier.update_with_france_connect(user_info)
expect(dossier.individual.gender).to eq 'Mme'
expect(dossier.individual.nom).to eq user_info.family_name
expect(dossier.individual.prenom).to eq user_info.given_name
}
end
describe '#for_procedure' do
let!(:procedure_1) { create(:procedure) }
let!(:procedure_2) { create(:procedure) }