models: require belong_to associations on champ
- Make `champ.dossier` a requirement; - Move the dossier_id assignation to `before_validation` (otherwise the record is invalid, and never gets saved); - Allow specs to only build the champ (instead of saving it to the database), which bypasses the requirement to have a dossier.
This commit is contained in:
parent
eb22dc9d8f
commit
6328011f60
13 changed files with 318 additions and 274 deletions
|
@ -15,8 +15,8 @@
|
|||
# type_de_champ_id :integer
|
||||
#
|
||||
class Champ < ApplicationRecord
|
||||
belongs_to :dossier, -> { with_discarded }, inverse_of: :champs, touch: true
|
||||
belongs_to :type_de_champ, inverse_of: :champ
|
||||
belongs_to :dossier, -> { with_discarded }, inverse_of: :champs, touch: true, optional: false
|
||||
belongs_to :type_de_champ, inverse_of: :champ, optional: false
|
||||
belongs_to :parent, class_name: 'Champ', optional: true
|
||||
has_many :commentaires
|
||||
has_one_attached :piece_justificative_file
|
||||
|
@ -49,7 +49,7 @@ class Champ < ApplicationRecord
|
|||
scope :ordered, -> { includes(:type_de_champ).order(:row, 'types_de_champ.order_place') }
|
||||
scope :root, -> { where(parent_id: nil) }
|
||||
|
||||
before_create :set_dossier_id, if: :needs_dossier_id?
|
||||
before_validation :set_dossier_id, if: :needs_dossier_id?
|
||||
|
||||
validates :type_de_champ_id, uniqueness: { scope: [:dossier_id, :row] }
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
describe Champs::SiretController, type: :controller do
|
||||
let(:user) { create(:user) }
|
||||
let(:procedure) { create(:procedure, :published) }
|
||||
let(:procedure) do
|
||||
tdc_siret = build(:type_de_champ_siret, procedure: nil)
|
||||
create(:procedure, :published, types_de_champ: [tdc_siret])
|
||||
end
|
||||
|
||||
describe '#show' do
|
||||
let(:dossier) { create(:dossier, user: user, procedure: procedure) }
|
||||
let(:champ) do
|
||||
d = dossier
|
||||
type_de_champ = create(:type_de_champ_siret, procedure: procedure)
|
||||
type_de_champ.champ.create(dossier: d, value: nil, etablissement: nil)
|
||||
end
|
||||
let(:champ) { dossier.champs.first }
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
champ_id: champ.id,
|
||||
|
@ -27,6 +27,7 @@ describe Champs::SiretController, type: :controller do
|
|||
let(:api_etablissement_status) { 200 }
|
||||
let(:api_etablissement_body) { File.read('spec/fixtures/files/api_entreprise/etablissements.json') }
|
||||
let(:token_expired) { false }
|
||||
|
||||
before do
|
||||
sign_in user
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*token=/)
|
||||
|
@ -112,7 +113,7 @@ describe Champs::SiretController, type: :controller do
|
|||
champ.reload
|
||||
expect(champ.value).to eq(siret)
|
||||
expect(champ.etablissement.siret).to eq(siret)
|
||||
expect(champ.reload.etablissement.naf).to eq("6202A")
|
||||
expect(champ.etablissement.naf).to eq("6202A")
|
||||
expect(dossier.reload.etablissement).to eq(nil)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -561,32 +561,35 @@ describe Instructeurs::DossiersController, type: :controller do
|
|||
|
||||
describe "#update_annotations" do
|
||||
let(:champ_multiple_drop_down_list) do
|
||||
create(:type_de_champ_multiple_drop_down_list, :private, libelle: 'libelle').champ.create
|
||||
tdc = create(:type_de_champ_multiple_drop_down_list, :private, procedure: procedure, libelle: 'libelle')
|
||||
create(:champ_multiple_drop_down_list, :private, type_de_champ: tdc, dossier: dossier)
|
||||
end
|
||||
|
||||
let(:champ_linked_drop_down_list) do
|
||||
create(:type_de_champ_linked_drop_down_list, :private, libelle: 'libelle').champ.create
|
||||
tdc = create(:type_de_champ_linked_drop_down_list, :private, procedure: procedure, libelle: 'libelle')
|
||||
create(:champ_linked_drop_down_list, :private, type_de_champ: tdc, dossier: dossier)
|
||||
end
|
||||
|
||||
let(:champ_datetime) do
|
||||
create(:type_de_champ_datetime, :private, libelle: 'libelle').champ.create
|
||||
tdc = create(:type_de_champ_datetime, :private, procedure: procedure, libelle: 'libelle')
|
||||
create(:champ_datetime, :private, type_de_champ: tdc, dossier: dossier)
|
||||
end
|
||||
|
||||
let(:champ_repetition) do
|
||||
tdc = create(:type_de_champ_repetition, :private, libelle: 'libelle')
|
||||
tdc.types_de_champ << create(:type_de_champ_text, libelle: 'libelle')
|
||||
champ = tdc.champ.create
|
||||
tdc = create(:type_de_champ_repetition, :private, :with_types_de_champ, procedure: procedure, libelle: 'libelle')
|
||||
tdc.types_de_champ << create(:type_de_champ_text, procedure: procedure, libelle: 'libelle')
|
||||
champ = create(:champ_repetition, :private, type_de_champ: tdc, dossier: dossier)
|
||||
champ.add_row
|
||||
champ
|
||||
end
|
||||
|
||||
let(:dossier) do
|
||||
create(:dossier, :en_construction, procedure: procedure, champs_private: [champ_multiple_drop_down_list, champ_linked_drop_down_list, champ_datetime, champ_repetition])
|
||||
end
|
||||
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
|
||||
|
||||
let(:now) { Time.zone.parse('01/01/2100') }
|
||||
|
||||
before do
|
||||
dossier.champs_private << [champ_multiple_drop_down_list, champ_linked_drop_down_list, champ_datetime, champ_repetition]
|
||||
|
||||
Timecop.freeze(now)
|
||||
patch :update_annotations, params: params
|
||||
|
||||
|
|
|
@ -1,197 +1,220 @@
|
|||
FactoryBot.define do
|
||||
factory :champ do
|
||||
type_de_champ { create(:type_de_champ) }
|
||||
add_attribute(:private) { false }
|
||||
|
||||
trait :checkbox do
|
||||
type_de_champ { create(:type_de_champ_checkbox) }
|
||||
end
|
||||
dossier { association :dossier }
|
||||
type_de_champ { association :type_de_champ, procedure: dossier.procedure }
|
||||
|
||||
trait :header_section do
|
||||
type_de_champ { create(:type_de_champ_header_section) }
|
||||
end
|
||||
|
||||
trait :explication do
|
||||
type_de_champ { create(:type_de_champ_explication) }
|
||||
end
|
||||
|
||||
trait :dossier_link do
|
||||
type_de_champ { create(:type_de_champ_dossier_link) }
|
||||
end
|
||||
|
||||
trait :piece_justificative do
|
||||
type_de_champ { create(:type_de_champ_piece_justificative) }
|
||||
trait :private do
|
||||
add_attribute(:private) { true }
|
||||
end
|
||||
|
||||
trait :with_piece_justificative_file do
|
||||
after(:create) do |champ, _evaluator|
|
||||
after(:build) do |champ, _evaluator|
|
||||
champ.piece_justificative_file.attach(io: StringIO.new("toto"), filename: "toto.txt", content_type: "text/plain")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
factory :champ_text, class: 'Champs::TextChamp' do
|
||||
type_de_champ { create(:type_de_champ_text) }
|
||||
value { 'text' }
|
||||
end
|
||||
|
||||
factory :champ_textarea, class: 'Champs::TextareaChamp' do
|
||||
type_de_champ { create(:type_de_champ_textarea) }
|
||||
value { 'textarea' }
|
||||
end
|
||||
|
||||
factory :champ_date, class: 'Champs::DateChamp' do
|
||||
type_de_champ { create(:type_de_champ_date) }
|
||||
value { '2019-07-10' }
|
||||
end
|
||||
|
||||
factory :champ_datetime, class: 'Champs::DatetimeChamp' do
|
||||
type_de_champ { create(:type_de_champ_datetime) }
|
||||
value { '15/09/1962 15:35' }
|
||||
end
|
||||
|
||||
factory :champ_number, class: 'Champs::NumberChamp' do
|
||||
type_de_champ { create(:type_de_champ_number) }
|
||||
value { '42' }
|
||||
end
|
||||
|
||||
factory :champ_decimal_number, class: 'Champs::DecimalNumberChamp' do
|
||||
type_de_champ { create(:type_de_champ_decimal_number) }
|
||||
value { '42.1' }
|
||||
end
|
||||
|
||||
factory :champ_integer_number, class: 'Champs::IntegerNumberChamp' do
|
||||
type_de_champ { create(:type_de_champ_integer_number) }
|
||||
value { '42' }
|
||||
end
|
||||
|
||||
factory :champ_checkbox, class: 'Champs::CheckboxChamp' do
|
||||
type_de_champ { create(:type_de_champ_checkbox) }
|
||||
value { 'on' }
|
||||
end
|
||||
|
||||
factory :champ_civilite, class: 'Champs::CiviliteChamp' do
|
||||
type_de_champ { create(:type_de_champ_civilite) }
|
||||
value { 'M.' }
|
||||
end
|
||||
|
||||
factory :champ_email, class: 'Champs::EmailChamp' do
|
||||
type_de_champ { create(:type_de_champ_email) }
|
||||
value { 'yoda@beta.gouv.fr' }
|
||||
end
|
||||
|
||||
factory :champ_phone, class: 'Champs::PhoneChamp' do
|
||||
type_de_champ { create(:type_de_champ_phone) }
|
||||
value { '0666666666' }
|
||||
end
|
||||
|
||||
factory :champ_address, class: 'Champs::AddressChamp' do
|
||||
type_de_champ { create(:type_de_champ_address) }
|
||||
value { '2 rue des Démarches' }
|
||||
end
|
||||
|
||||
factory :champ_yes_no, class: 'Champs::YesNoChamp' do
|
||||
type_de_champ { create(:type_de_champ_yes_no) }
|
||||
value { 'true' }
|
||||
end
|
||||
|
||||
factory :champ_drop_down_list, class: 'Champs::DropDownListChamp' do
|
||||
type_de_champ { create(:type_de_champ_drop_down_list) }
|
||||
value { 'choix 1' }
|
||||
end
|
||||
|
||||
factory :champ_multiple_drop_down_list, class: 'Champs::MultipleDropDownListChamp' do
|
||||
type_de_champ { create(:type_de_champ_multiple_drop_down_list) }
|
||||
value { '["choix 1", "choix 2"]' }
|
||||
end
|
||||
|
||||
factory :champ_linked_drop_down_list, class: 'Champs::LinkedDropDownListChamp' do
|
||||
type_de_champ { create(:type_de_champ_linked_drop_down_list) }
|
||||
value { '["categorie 1", "choix 1"]' }
|
||||
end
|
||||
|
||||
factory :champ_pays, class: 'Champs::PaysChamp' do
|
||||
type_de_champ { create(:type_de_champ_pays) }
|
||||
value { 'France' }
|
||||
end
|
||||
|
||||
factory :champ_regions, class: 'Champs::RegionChamp' do
|
||||
type_de_champ { create(:type_de_champ_regions) }
|
||||
value { 'Guadeloupe' }
|
||||
end
|
||||
|
||||
factory :champ_departements, class: 'Champs::DepartementChamp' do
|
||||
type_de_champ { create(:type_de_champ_departements) }
|
||||
value { '971 - Guadeloupe' }
|
||||
end
|
||||
|
||||
factory :champ_communes, class: 'Champs::CommuneChamp' do
|
||||
type_de_champ { create(:type_de_champ_communes) }
|
||||
value { 'Paris' }
|
||||
end
|
||||
|
||||
factory :champ_engagement, class: 'Champs::EngagementChamp' do
|
||||
type_de_champ { create(:type_de_champ_engagement) }
|
||||
value { 'true' }
|
||||
end
|
||||
|
||||
factory :champ_header_section, class: 'Champs::HeaderSectionChamp' do
|
||||
type_de_champ { create(:type_de_champ_header_section) }
|
||||
value { 'une section' }
|
||||
end
|
||||
|
||||
factory :champ_explication, class: 'Champs::ExplicationChamp' do
|
||||
type_de_champ { create(:type_de_champ_explication) }
|
||||
value { '' }
|
||||
end
|
||||
|
||||
factory :champ_dossier_link, class: 'Champs::DossierLinkChamp' do
|
||||
type_de_champ { create(:type_de_champ_dossier_link) }
|
||||
value { create(:dossier).id }
|
||||
end
|
||||
|
||||
factory :champ_piece_justificative, class: 'Champs::PieceJustificativeChamp' do
|
||||
type_de_champ { create(:type_de_champ_piece_justificative) }
|
||||
|
||||
after(:build) do |champ, _evaluator|
|
||||
champ.piece_justificative_file.attach(io: StringIO.new("toto"), filename: "toto.txt", content_type: "text/plain")
|
||||
factory :champ_text, class: 'Champs::TextChamp' do
|
||||
type_de_champ { association :type_de_champ_text, procedure: dossier.procedure }
|
||||
value { 'text' }
|
||||
end
|
||||
end
|
||||
|
||||
factory :champ_carte, class: 'Champs::CarteChamp' do
|
||||
type_de_champ { create(:type_de_champ_carte) }
|
||||
end
|
||||
|
||||
factory :champ_siret, class: 'Champs::SiretChamp' do
|
||||
association :type_de_champ, factory: [:type_de_champ_siret]
|
||||
association :etablissement, factory: [:etablissement]
|
||||
value { '44011762001530' }
|
||||
end
|
||||
|
||||
factory :champ_repetition, class: 'Champs::RepetitionChamp' do
|
||||
type_de_champ { create(:type_de_champ_repetition) }
|
||||
|
||||
after(:build) do |champ_repetition, _evaluator|
|
||||
type_de_champ_text = create(:type_de_champ_text, order_place: 0, parent: champ_repetition.type_de_champ, libelle: 'Nom')
|
||||
type_de_champ_number = create(:type_de_champ_number, order_place: 1, parent: champ_repetition.type_de_champ, libelle: 'Age')
|
||||
|
||||
create(:champ_text, row: 0, type_de_champ: type_de_champ_text, parent: champ_repetition)
|
||||
create(:champ_number, row: 0, type_de_champ: type_de_champ_number, parent: champ_repetition)
|
||||
create(:champ_text, row: 1, type_de_champ: type_de_champ_text, parent: champ_repetition)
|
||||
create(:champ_number, row: 1, type_de_champ: type_de_champ_number, parent: champ_repetition)
|
||||
factory :champ_textarea, class: 'Champs::TextareaChamp' do
|
||||
type_de_champ { association :type_de_champ_textarea, procedure: dossier.procedure }
|
||||
value { 'textarea' }
|
||||
end
|
||||
end
|
||||
|
||||
factory :champ_repetition_with_piece_jointe, class: 'Champs::RepetitionChamp' do
|
||||
type_de_champ { create(:type_de_champ_repetition) }
|
||||
factory :champ_date, class: 'Champs::DateChamp' do
|
||||
type_de_champ { association :type_de_champ_date, procedure: dossier.procedure }
|
||||
value { '2019-07-10' }
|
||||
end
|
||||
|
||||
after(:build) do |champ_repetition, _evaluator|
|
||||
type_de_champ_pj0 = create(:type_de_champ_piece_justificative, order_place: 0, parent: champ_repetition.type_de_champ, libelle: 'Justificatif de domicile')
|
||||
type_de_champ_pj1 = create(:type_de_champ_piece_justificative, order_place: 1, parent: champ_repetition.type_de_champ, libelle: 'Carte d\'identité')
|
||||
factory :champ_datetime, class: 'Champs::DatetimeChamp' do
|
||||
type_de_champ { association :type_de_champ_datetime, procedure: dossier.procedure }
|
||||
value { '15/09/1962 15:35' }
|
||||
end
|
||||
|
||||
create(:champ_piece_justificative, row: 0, type_de_champ: type_de_champ_pj0, parent: champ_repetition)
|
||||
create(:champ_piece_justificative, row: 0, type_de_champ: type_de_champ_pj1, parent: champ_repetition)
|
||||
create(:champ_piece_justificative, row: 1, type_de_champ: type_de_champ_pj0, parent: champ_repetition)
|
||||
create(:champ_piece_justificative, row: 1, type_de_champ: type_de_champ_pj1, parent: champ_repetition)
|
||||
factory :champ_number, class: 'Champs::NumberChamp' do
|
||||
type_de_champ { association :type_de_champ_number, procedure: dossier.procedure }
|
||||
value { '42' }
|
||||
end
|
||||
|
||||
factory :champ_decimal_number, class: 'Champs::DecimalNumberChamp' do
|
||||
type_de_champ { association :type_de_champ_decimal_number, procedure: dossier.procedure }
|
||||
value { '42.1' }
|
||||
end
|
||||
|
||||
factory :champ_integer_number, class: 'Champs::IntegerNumberChamp' do
|
||||
type_de_champ { association :type_de_champ_integer_number, procedure: dossier.procedure }
|
||||
value { '42' }
|
||||
end
|
||||
|
||||
factory :champ_checkbox, class: 'Champs::CheckboxChamp' do
|
||||
type_de_champ { association :type_de_champ_checkbox, procedure: dossier.procedure }
|
||||
value { 'on' }
|
||||
end
|
||||
|
||||
factory :champ_civilite, class: 'Champs::CiviliteChamp' do
|
||||
type_de_champ { association :type_de_champ_civilite, procedure: dossier.procedure }
|
||||
value { 'M.' }
|
||||
end
|
||||
|
||||
factory :champ_email, class: 'Champs::EmailChamp' do
|
||||
type_de_champ { association :type_de_champ_email, procedure: dossier.procedure }
|
||||
value { 'yoda@beta.gouv.fr' }
|
||||
end
|
||||
|
||||
factory :champ_phone, class: 'Champs::PhoneChamp' do
|
||||
type_de_champ { association :type_de_champ_phone, procedure: dossier.procedure }
|
||||
value { '0666666666' }
|
||||
end
|
||||
|
||||
factory :champ_address, class: 'Champs::AddressChamp' do
|
||||
type_de_champ { association :type_de_champ_address, procedure: dossier.procedure }
|
||||
value { '2 rue des Démarches' }
|
||||
end
|
||||
|
||||
factory :champ_yes_no, class: 'Champs::YesNoChamp' do
|
||||
type_de_champ { association :type_de_champ_yes_no, procedure: dossier.procedure }
|
||||
value { 'true' }
|
||||
end
|
||||
|
||||
factory :champ_drop_down_list, class: 'Champs::DropDownListChamp' do
|
||||
type_de_champ { association :type_de_champ_drop_down_list, procedure: dossier.procedure }
|
||||
value { 'choix 1' }
|
||||
end
|
||||
|
||||
factory :champ_multiple_drop_down_list, class: 'Champs::MultipleDropDownListChamp' do
|
||||
type_de_champ { association :type_de_champ_multiple_drop_down_list, procedure: dossier.procedure }
|
||||
value { '["choix 1", "choix 2"]' }
|
||||
end
|
||||
|
||||
factory :champ_linked_drop_down_list, class: 'Champs::LinkedDropDownListChamp' do
|
||||
type_de_champ { association :type_de_champ_linked_drop_down_list, procedure: dossier.procedure }
|
||||
value { '["categorie 1", "choix 1"]' }
|
||||
end
|
||||
|
||||
factory :champ_pays, class: 'Champs::PaysChamp' do
|
||||
type_de_champ { association :type_de_champ_pays, procedure: dossier.procedure }
|
||||
value { 'France' }
|
||||
end
|
||||
|
||||
factory :champ_regions, class: 'Champs::RegionChamp' do
|
||||
type_de_champ { association :type_de_champ_regions, procedure: dossier.procedure }
|
||||
value { 'Guadeloupe' }
|
||||
end
|
||||
|
||||
factory :champ_departements, class: 'Champs::DepartementChamp' do
|
||||
type_de_champ { association :type_de_champ_departements, procedure: dossier.procedure }
|
||||
value { '971 - Guadeloupe' }
|
||||
end
|
||||
|
||||
factory :champ_communes, class: 'Champs::CommuneChamp' do
|
||||
type_de_champ { association :type_de_champ_communes, procedure: dossier.procedure }
|
||||
value { 'Paris' }
|
||||
end
|
||||
|
||||
factory :champ_engagement, class: 'Champs::EngagementChamp' do
|
||||
type_de_champ { association :type_de_champ_engagement, procedure: dossier.procedure }
|
||||
value { 'true' }
|
||||
end
|
||||
|
||||
factory :champ_header_section, class: 'Champs::HeaderSectionChamp' do
|
||||
type_de_champ { association :type_de_champ_header_section, procedure: dossier.procedure }
|
||||
value { 'une section' }
|
||||
end
|
||||
|
||||
factory :champ_explication, class: 'Champs::ExplicationChamp' do
|
||||
type_de_champ { association :type_de_champ_explication, procedure: dossier.procedure }
|
||||
value { '' }
|
||||
end
|
||||
|
||||
factory :champ_dossier_link, class: 'Champs::DossierLinkChamp' do
|
||||
type_de_champ { association :type_de_champ_dossier_link, procedure: dossier.procedure }
|
||||
value { create(:dossier).id }
|
||||
end
|
||||
|
||||
factory :champ_piece_justificative, class: 'Champs::PieceJustificativeChamp' do
|
||||
type_de_champ { association :type_de_champ_piece_justificative, procedure: dossier.procedure }
|
||||
|
||||
after(:build) do |champ, _evaluator|
|
||||
champ.piece_justificative_file.attach(io: StringIO.new("toto"), filename: "toto.txt", content_type: "text/plain")
|
||||
end
|
||||
end
|
||||
|
||||
factory :champ_carte, class: 'Champs::CarteChamp' do
|
||||
type_de_champ { association :type_de_champ_carte, procedure: dossier.procedure }
|
||||
end
|
||||
|
||||
factory :champ_siret, class: 'Champs::SiretChamp' do
|
||||
association :type_de_champ, factory: [:type_de_champ_siret]
|
||||
association :etablissement, factory: [:etablissement]
|
||||
value { '44011762001530' }
|
||||
end
|
||||
|
||||
factory :champ_repetition, class: 'Champs::RepetitionChamp' do
|
||||
type_de_champ { association :type_de_champ_repetition, procedure: dossier.procedure }
|
||||
|
||||
after(:build) do |champ_repetition, _evaluator|
|
||||
types_de_champ = champ_repetition.type_de_champ.types_de_champ
|
||||
existing_type_de_champ_text = types_de_champ.find { |tdc| tdc.libelle == 'Nom' }
|
||||
type_de_champ_text = existing_type_de_champ_text || build(
|
||||
:type_de_champ_text,
|
||||
order_place: 0,
|
||||
procedure: champ_repetition.dossier.procedure,
|
||||
parent: champ_repetition.type_de_champ,
|
||||
libelle: 'Nom'
|
||||
)
|
||||
|
||||
types_de_champ << type_de_champ_text
|
||||
existing_type_de_champ_number = types_de_champ.find { |tdc| tdc.libelle == 'Age' }
|
||||
type_de_champ_number = existing_type_de_champ_number || build(
|
||||
:type_de_champ_number,
|
||||
order_place: 1,
|
||||
procedure: champ_repetition.dossier.procedure,
|
||||
parent: champ_repetition.type_de_champ,
|
||||
libelle: 'Age'
|
||||
)
|
||||
types_de_champ << type_de_champ_number
|
||||
|
||||
champ_repetition.champs << [
|
||||
build(:champ_text, dossier: champ_repetition.dossier, row: 0, type_de_champ: type_de_champ_text, parent: champ_repetition),
|
||||
build(:champ_number, dossier: champ_repetition.dossier, row: 0, type_de_champ: type_de_champ_number, parent: champ_repetition),
|
||||
build(:champ_text, dossier: champ_repetition.dossier, row: 1, type_de_champ: type_de_champ_text, parent: champ_repetition),
|
||||
build(:champ_number, dossier: champ_repetition.dossier, row: 1, type_de_champ: type_de_champ_number, parent: champ_repetition)
|
||||
]
|
||||
end
|
||||
|
||||
trait :without_champs do
|
||||
after(:build) do |champ_repetition, _evaluator|
|
||||
champ_repetition.champs = []
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
factory :champ_repetition_with_piece_jointe, class: 'Champs::RepetitionChamp' do
|
||||
type_de_champ { association :type_de_champ_repetition, procedure: dossier.procedure }
|
||||
|
||||
after(:build) do |champ_repetition, _evaluator|
|
||||
type_de_champ_pj0 = build(:type_de_champ_piece_justificative,
|
||||
procedure: champ_repetition.dossier.procedure,
|
||||
order_place: 0,
|
||||
parent: champ_repetition.type_de_champ,
|
||||
libelle: 'Justificatif de domicile')
|
||||
type_de_champ_pj1 = build(:type_de_champ_piece_justificative,
|
||||
procedure: champ_repetition.dossier.procedure,
|
||||
order_place: 1,
|
||||
parent: champ_repetition.type_de_champ,
|
||||
libelle: 'Carte d\'identité')
|
||||
|
||||
champ_repetition.champs << [
|
||||
build(:champ_piece_justificative, dossier: champ_repetition.dossier, row: 0, type_de_champ: type_de_champ_pj0),
|
||||
build(:champ_piece_justificative, dossier: champ_repetition.dossier, row: 0, type_de_champ: type_de_champ_pj1),
|
||||
build(:champ_piece_justificative, dossier: champ_repetition.dossier, row: 1, type_de_champ: type_de_champ_pj0),
|
||||
build(:champ_piece_justificative, dossier: champ_repetition.dossier, row: 1, type_de_champ: type_de_champ_pj1)
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -203,7 +203,7 @@ FactoryBot.define do
|
|||
trait :with_all_champs do
|
||||
after(:create) do |dossier, _evaluator|
|
||||
dossier.champs = dossier.procedure.types_de_champ.map do |type_de_champ|
|
||||
build(:"champ_#{type_de_champ.type_champ}", type_de_champ: type_de_champ)
|
||||
build(:"champ_#{type_de_champ.type_champ}", dossier: dossier, type_de_champ: type_de_champ)
|
||||
end
|
||||
dossier.save!
|
||||
end
|
||||
|
@ -212,7 +212,7 @@ FactoryBot.define do
|
|||
trait :with_all_annotations do
|
||||
after(:create) do |dossier, _evaluator|
|
||||
dossier.champs = dossier.procedure.types_de_champ.map do |type_de_champ|
|
||||
build(:"champ_#{type_de_champ.type_champ}", type_de_champ: type_de_champ)
|
||||
build(:"champ_#{type_de_champ.type_champ}", dossier: dossier, type_de_champ: type_de_champ)
|
||||
end
|
||||
dossier.save!
|
||||
end
|
||||
|
|
|
@ -232,10 +232,10 @@ FactoryBot.define do
|
|||
if libelle == 'drop_down_list'
|
||||
libelle = 'simple_drop_down_list'
|
||||
end
|
||||
build(:"type_de_champ_#{type_champ}", mandatory: true, libelle: libelle, order_place: index)
|
||||
build(:"type_de_champ_#{type_champ}", procedure: procedure, mandatory: true, libelle: libelle, order_place: index)
|
||||
end
|
||||
procedure.types_de_champ << build(:type_de_champ_drop_down_list, :long, mandatory: true, libelle: 'simple_choice_drop_down_list_long')
|
||||
procedure.types_de_champ << build(:type_de_champ_multiple_drop_down_list, :long, mandatory: true, libelle: 'multiple_choice_drop_down_list_long')
|
||||
procedure.types_de_champ << build(:type_de_champ_drop_down_list, :long, procedure: procedure, mandatory: true, libelle: 'simple_choice_drop_down_list_long')
|
||||
procedure.types_de_champ << build(:type_de_champ_multiple_drop_down_list, :long, procedure: procedure, mandatory: true, libelle: 'multiple_choice_drop_down_list_long')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -245,7 +245,7 @@ FactoryBot.define do
|
|||
if libelle == 'drop_down_list'
|
||||
libelle = 'simple_drop_down_list'
|
||||
end
|
||||
build(:"type_de_champ_#{type_champ}", libelle: libelle, order_place: index)
|
||||
build(:"type_de_champ_#{type_champ}", procedure: procedure, libelle: libelle, order_place: index)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -256,7 +256,7 @@ FactoryBot.define do
|
|||
if libelle == 'drop_down_list'
|
||||
libelle = 'simple_drop_down_list'
|
||||
end
|
||||
build(:"type_de_champ_#{type_champ}", private: true, libelle: libelle, order_place: index)
|
||||
build(:"type_de_champ_#{type_champ}", procedure: procedure, private: true, libelle: libelle, order_place: index)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -94,7 +94,7 @@ FactoryBot.define do
|
|||
factory :type_de_champ_piece_justificative do
|
||||
type_champ { TypeDeChamp.type_champs.fetch(:piece_justificative) }
|
||||
|
||||
after(:create) do |tc, _evaluator|
|
||||
after(:build) do |tc, _evaluator|
|
||||
tc.piece_justificative_template.attach(io: StringIO.new("toto"), filename: "toto.txt", content_type: "text/plain")
|
||||
end
|
||||
end
|
||||
|
@ -109,7 +109,7 @@ FactoryBot.define do
|
|||
|
||||
trait :with_types_de_champ do
|
||||
after(:build) do |type_de_champ, _evaluator|
|
||||
type_de_champ.types_de_champ << create(:type_de_champ, libelle: 'sub type de champ')
|
||||
type_de_champ.types_de_champ << build(:type_de_champ, procedure: type_de_champ.procedure, libelle: 'sub type de champ')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ RSpec.describe VirusScannerJob, type: :job do
|
|||
include ActiveJob::TestHelper
|
||||
|
||||
let(:champ) do
|
||||
champ = create(:champ, :piece_justificative)
|
||||
champ = create(:champ_piece_justificative)
|
||||
champ.piece_justificative_file.attach(io: StringIO.new("toto"), filename: "toto.txt", content_type: "text/plain")
|
||||
champ.save
|
||||
champ
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
describe ActiveStorage::DownloadableFile do
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:dossier) { create(:dossier, :en_construction) }
|
||||
|
||||
subject(:list) { ActiveStorage::DownloadableFile.create_list_from_dossier(dossier) }
|
||||
|
||||
|
@ -10,7 +10,7 @@ describe ActiveStorage::DownloadableFile do
|
|||
|
||||
context 'when there is a piece_justificative' do
|
||||
before do
|
||||
dossier.champs << create(:champ, :piece_justificative, :with_piece_justificative_file)
|
||||
dossier.champs << create(:champ_piece_justificative, :with_piece_justificative_file, dossier: dossier)
|
||||
end
|
||||
|
||||
it { expect(list.length).to eq 1 }
|
||||
|
@ -18,15 +18,16 @@ describe ActiveStorage::DownloadableFile do
|
|||
|
||||
context 'when there is a private piece_justificative' do
|
||||
before do
|
||||
dossier.champs_private << create(:champ, :piece_justificative, :with_piece_justificative_file, private: true)
|
||||
dossier.champs_private << create(:champ_piece_justificative, :with_piece_justificative_file, private: true, dossier: dossier)
|
||||
end
|
||||
|
||||
it { expect(list.length).to eq 1 }
|
||||
end
|
||||
|
||||
context 'when there is a repetition bloc' do
|
||||
let(:champ) { build(:champ_repetition_with_piece_jointe) }
|
||||
let(:dossier) { create(:dossier, :en_construction, champs: [champ]) }
|
||||
before do
|
||||
dossier.champs << build(:champ_repetition_with_piece_jointe, dossier: dossier)
|
||||
end
|
||||
|
||||
it 'should have 4 piece_justificatives' do
|
||||
expect(list.size).to eq 4
|
||||
|
@ -35,7 +36,7 @@ describe ActiveStorage::DownloadableFile do
|
|||
|
||||
context 'when there is a message with no attachment' do
|
||||
before do
|
||||
dossier.commentaires << build(:commentaire, dossier: dossier)
|
||||
dossier.commentaires << create(:commentaire, dossier: dossier)
|
||||
end
|
||||
|
||||
it { expect(list.length).to eq 0 }
|
||||
|
@ -43,7 +44,7 @@ describe ActiveStorage::DownloadableFile do
|
|||
|
||||
context 'when there is a message with an attachment' do
|
||||
before do
|
||||
dossier.commentaires << build(:commentaire, :with_file, dossier: dossier)
|
||||
dossier.commentaires << create(:commentaire, :with_file, dossier: dossier)
|
||||
end
|
||||
|
||||
it { expect(list.length).to eq 1 }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
shared_examples 'champ_spec' do
|
||||
describe 'mandatory_and_blank?' do
|
||||
let(:type_de_champ) { build(:type_de_champ, mandatory: mandatory) }
|
||||
let(:champ) { type_de_champ.champ.build(value: value) }
|
||||
let(:champ) { build(:champ, type_de_champ: type_de_champ, value: value) }
|
||||
let(:value) { '' }
|
||||
let(:mandatory) { true }
|
||||
|
||||
|
@ -33,8 +33,7 @@ shared_examples 'champ_spec' do
|
|||
end
|
||||
|
||||
context "when type_champ=date" do
|
||||
let(:type_de_champ) { create(:type_de_champ_date) }
|
||||
let(:champ) { type_de_champ.champ.create }
|
||||
let(:champ) { build(:champ_date) }
|
||||
|
||||
it "should convert %d/%m/%Y format to ISO" do
|
||||
champ.value = "31/12/2017"
|
||||
|
|
|
@ -47,7 +47,7 @@ describe Champ do
|
|||
let(:public_champ) { dossier.champs.first }
|
||||
let(:private_champ) { dossier.champs_private.first }
|
||||
let(:champ_in_repetition) { dossier.champs.find(&:repetition?).champs.first }
|
||||
let(:standalone_champ) { create(:champ, dossier: nil) }
|
||||
let(:standalone_champ) { build(:champ, type_de_champ: build(:type_de_champ), dossier: nil) }
|
||||
|
||||
it 'returns the sibling champs of a champ' do
|
||||
expect(public_champ.siblings).to eq(dossier.champs)
|
||||
|
@ -58,10 +58,9 @@ describe Champ do
|
|||
end
|
||||
|
||||
describe '#format_datetime' do
|
||||
let(:type_de_champ) { build(:type_de_champ_datetime) }
|
||||
let(:champ) { type_de_champ.champ.build(value: value) }
|
||||
let(:champ) { build(:champ_datetime, value: value) }
|
||||
|
||||
before { champ.save }
|
||||
before { champ.save! }
|
||||
|
||||
context 'when the value is sent by a modern browser' do
|
||||
let(:value) { '2017-12-31 10:23' }
|
||||
|
@ -77,10 +76,9 @@ describe Champ do
|
|||
end
|
||||
|
||||
describe '#multiple_select_to_string' do
|
||||
let(:type_de_champ) { build(:type_de_champ_multiple_drop_down_list) }
|
||||
let(:champ) { type_de_champ.champ.build(value: value) }
|
||||
let(:champ) { build(:champ_multiple_drop_down_list, value: value) }
|
||||
|
||||
before { champ.save }
|
||||
before { champ.save! }
|
||||
|
||||
# when using the old form, and the ChampsService Class
|
||||
# TODO: to remove
|
||||
|
@ -412,7 +410,7 @@ describe Champ do
|
|||
end
|
||||
|
||||
describe '#enqueue_virus_check' do
|
||||
let(:champ) { type_de_champ.champ.build(value: nil) }
|
||||
let(:champ) { build(:champ_piece_justificative, type_de_champ: type_de_champ) }
|
||||
|
||||
context 'when type_champ is type_de_champ_piece_justificative' do
|
||||
let(:type_de_champ) { create(:type_de_champ_piece_justificative) }
|
||||
|
@ -420,7 +418,7 @@ describe Champ do
|
|||
context 'and there is a blob' do
|
||||
before do
|
||||
champ.piece_justificative_file.attach(io: StringIO.new("toto"), filename: "toto.txt", content_type: "text/plain")
|
||||
champ.save
|
||||
champ.save!
|
||||
end
|
||||
|
||||
it { expect(champ.piece_justificative_file.virus_scanner.started?).to be_truthy }
|
||||
|
@ -428,50 +426,69 @@ describe Champ do
|
|||
end
|
||||
end
|
||||
|
||||
describe "repetition" do
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:champ) { Champs::RepetitionChamp.create(dossier: dossier) }
|
||||
let(:champ_text) { create(:champ_text, row: 0) }
|
||||
let(:champ_integer_number) { create(:champ_integer_number, row: 0) }
|
||||
let(:champ_text_attrs) { attributes_for(:champ_text, row: 1) }
|
||||
let(:champ_text_row_1) { create(:champ_text, row: 1, parent: champ) }
|
||||
describe 'repetition' do
|
||||
let(:procedure) { build(:procedure, :published, :with_type_de_champ, :with_type_de_champ_private) }
|
||||
let(:tdc_text) { build(:type_de_champ_text, procedure: procedure) }
|
||||
let(:tdc_integer) { build(:type_de_champ_integer_number, procedure: procedure) }
|
||||
let(:tdc_repetition) { build(:type_de_champ_repetition, procedure: procedure, types_de_champ: [tdc_text, tdc_integer]) }
|
||||
|
||||
it "associates nested champs to the parent dossier" do
|
||||
expect(champ.rows.size).to eq(0)
|
||||
dossier.reload
|
||||
expect(dossier.champs.size).to eq(2)
|
||||
let(:dossier) { create(:dossier, procedure: procedure) }
|
||||
let(:champ) { dossier.champs.find(&:repetition?) }
|
||||
let(:champ_text) { champ.champs.find { |c| c.type_champ == 'text' } }
|
||||
let(:champ_integer) { champ.champs.find { |c| c.type_champ == 'integer_number' } }
|
||||
let(:champ_text_attrs) { attributes_for(:champ_text, type_de_champ: tdc_text, row: 1) }
|
||||
|
||||
dossier.update(champs_attributes: [
|
||||
{
|
||||
id: champ.id,
|
||||
champs_attributes: [champ_text_attrs]
|
||||
}
|
||||
])
|
||||
before do
|
||||
procedure.types_de_champ << tdc_repetition
|
||||
procedure.save!
|
||||
procedure.reload
|
||||
end
|
||||
|
||||
champ.reload
|
||||
dossier.reload
|
||||
expect(dossier.champs.size).to eq(2)
|
||||
expect(champ.rows.size).to eq(1)
|
||||
context 'when creating the model directly' do
|
||||
let(:champ_text_row_1) { create(:champ_text, type_de_champ: tdc_text, row: 2, parent: champ, dossier: nil) }
|
||||
|
||||
expect(champ.champs.first.dossier).to eq(dossier)
|
||||
it 'associates nested champs to the parent dossier' do
|
||||
expect(champ_text_row_1.dossier_id).to eq(champ.dossier_id)
|
||||
end
|
||||
end
|
||||
|
||||
# Make champs ordered
|
||||
champ_integer_number.type_de_champ.update(order_place: 0)
|
||||
champ_text.type_de_champ.update(order_place: 1)
|
||||
context 'when updating using nested attributes' do
|
||||
subject do
|
||||
dossier.update!(champs_attributes: [
|
||||
{
|
||||
id: champ.id,
|
||||
champs_attributes: [champ_text_attrs]
|
||||
}
|
||||
])
|
||||
champ.reload
|
||||
dossier.reload
|
||||
end
|
||||
|
||||
champ.champs << champ_integer_number
|
||||
row = champ.reload.rows.first
|
||||
expect(row.size).to eq(1)
|
||||
expect(row.first).to eq(champ_integer_number)
|
||||
it 'associates nested champs to the parent dossier' do
|
||||
subject
|
||||
|
||||
champ.champs << champ_text
|
||||
row = champ.reload.rows.first
|
||||
expect(row.size).to eq(2)
|
||||
expect(row.second).to eq(champ_text)
|
||||
expect(dossier.champs.size).to eq(2)
|
||||
expect(champ.rows.size).to eq(2)
|
||||
second_row = champ.rows.second
|
||||
expect(second_row.size).to eq(1)
|
||||
expect(second_row.first.dossier).to eq(dossier)
|
||||
|
||||
expect(champ.rows.size).to eq(2)
|
||||
# Make champs ordered
|
||||
champ_integer.type_de_champ.update(order_place: 0)
|
||||
champ_text.type_de_champ.update(order_place: 1)
|
||||
|
||||
expect(champ_text_row_1.dossier_id).to eq(champ.dossier_id)
|
||||
champ.champs << champ_integer
|
||||
first_row = champ.reload.rows.first
|
||||
expect(first_row.size).to eq(2)
|
||||
expect(first_row.first).to eq(champ_integer)
|
||||
|
||||
champ.champs << champ_text
|
||||
first_row = champ.reload.rows.first
|
||||
expect(first_row.size).to eq(2)
|
||||
expect(first_row.second).to eq(champ_text)
|
||||
|
||||
expect(champ.rows.size).to eq(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,11 +21,11 @@ describe DossierSerializer do
|
|||
let(:dossier) { create(:dossier, :en_construction, procedure: create(:procedure, :published, :with_type_de_champ)) }
|
||||
|
||||
before do
|
||||
dossier.champs << create(:champ_carte)
|
||||
dossier.champs << create(:champ_siret)
|
||||
dossier.champs << create(:champ_integer_number)
|
||||
dossier.champs << create(:champ_decimal_number)
|
||||
dossier.champs << create(:champ_linked_drop_down_list)
|
||||
dossier.champs << build(:champ_carte)
|
||||
dossier.champs << build(:champ_siret)
|
||||
dossier.champs << build(:champ_integer_number)
|
||||
dossier.champs << build(:champ_decimal_number)
|
||||
dossier.champs << build(:champ_linked_drop_down_list)
|
||||
end
|
||||
|
||||
it {
|
||||
|
|
|
@ -13,11 +13,11 @@ describe 'shared/dossiers/champs.html.haml', type: :view do
|
|||
context "there are some champs" do
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:avis) { create :avis, dossier: dossier, instructeur: instructeur }
|
||||
let(:champ1) { create(:champ, :checkbox, value: "on") }
|
||||
let(:champ2) { create(:champ, :header_section, value: "Section") }
|
||||
let(:champ3) { create(:champ, :explication, value: "mazette") }
|
||||
let(:champ4) { create(:champ, :dossier_link, value: dossier.id) }
|
||||
let(:champ5) { create(:champ_textarea, value: "Some long text in a textarea.") }
|
||||
let(:champ1) { create(:champ_checkbox, dossier: dossier, value: "on") }
|
||||
let(:champ2) { create(:champ_header_section, dossier: dossier, value: "Section") }
|
||||
let(:champ3) { create(:champ_explication, dossier: dossier, value: "mazette") }
|
||||
let(:champ4) { create(:champ_dossier_link, dossier: dossier, value: dossier.id) }
|
||||
let(:champ5) { create(:champ_textarea, dossier: dossier, value: "Some long text in a textarea.") }
|
||||
let(:champs) { [champ1, champ2, champ3, champ4, champ5] }
|
||||
|
||||
before { dossier.avis << avis }
|
||||
|
@ -71,7 +71,7 @@ describe 'shared/dossiers/champs.html.haml', type: :view do
|
|||
context "with seen_at" do
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:nouveau_groupe_instructeur) { create(:groupe_instructeur, procedure: dossier.procedure) }
|
||||
let(:champ1) { create(:champ, :checkbox, value: "on") }
|
||||
let(:champ1) { create(:champ_checkbox, dossier: dossier, value: "on") }
|
||||
let(:champs) { [champ1] }
|
||||
|
||||
context "with a demande_seen_at after groupe_instructeur_updated_at" do
|
||||
|
@ -96,7 +96,7 @@ describe 'shared/dossiers/champs.html.haml', type: :view do
|
|||
|
||||
context "with a dossier champ, but we are not authorized to acces the dossier" do
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:champ) { create(:champ, :dossier_link, value: dossier.id) }
|
||||
let(:champ) { create(:champ_dossier_link, dossier: dossier, value: dossier.id) }
|
||||
let(:champs) { [champ] }
|
||||
|
||||
it { is_expected.not_to have_link("Dossier nº #{dossier.id}") }
|
||||
|
@ -106,7 +106,7 @@ describe 'shared/dossiers/champs.html.haml', type: :view do
|
|||
|
||||
context "with a dossier_link champ but without value" do
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:champ) { create(:champ, :dossier_link, value: nil) }
|
||||
let(:champ) { create(:champ_dossier_link, dossier: dossier, value: nil) }
|
||||
let(:champs) { [champ] }
|
||||
|
||||
it { is_expected.to include("Pas de dossier associé") }
|
||||
|
@ -114,7 +114,7 @@ describe 'shared/dossiers/champs.html.haml', type: :view do
|
|||
|
||||
context "with seen_at" do
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:champ1) { create(:champ, :checkbox, value: "on") }
|
||||
let(:champ1) { create(:champ_checkbox, dossier: dossier, value: "on") }
|
||||
let(:champs) { [champ1] }
|
||||
|
||||
context "with a demande_seen_at after champ updated_at" do
|
||||
|
|
Loading…
Reference in a new issue