refactor(champs): update specs

This commit is contained in:
Paul Chavard 2024-11-26 22:15:26 +01:00
parent 474d206ee1
commit 56b0b156bf
No known key found for this signature in database
19 changed files with 83 additions and 83 deletions

View file

@ -2,8 +2,8 @@
describe EditableChamp::ExplicationComponent, type: :component do
let(:procedure) { create(:procedure, :published, types_de_champ_public:) }
let(:dossier) { create(:dossier, :with_populated_champs, procedure:) }
let(:champ) { dossier.champs.first }
let(:dossier) { create(:dossier, procedure:) }
let(:champ) { dossier.project_champs_public.first }
let(:component) {
described_class.new(form: instance_double(ActionView::Helpers::FormBuilder, object_name: "dossier[champs_public_attributes]"), champ:)

View file

@ -40,20 +40,7 @@ describe Champs::PieceJustificativeController, type: :controller do
end
context 'when the file is invalid' do
let(:file) { fixture_file_upload('spec/fixtures/files/invalid_file_format.json', 'application/json') }
# TODO: for now there are no validators on the champ piece_justificative_file,
# so we have to mock a failing validation.
# Once the validators will be enabled, remove those mocks, and let the usual
# validation fail naturally.
#
# See https://github.com/betagouv/demarches-simplifiees.fr/issues/4926
before do
champ
expect_any_instance_of(Champs::PieceJustificativeChamp).to receive(:save).and_return(false)
expect_any_instance_of(Champs::PieceJustificativeChamp).to receive(:errors)
.and_return(double(full_messages: ['La pièce justificative nest pas dun type accepté']))
end
let(:file) { fixture_file_upload('spec/fixtures/files/invalid_file_format.json', 'bad/bad') }
it 'doesnt attach the file' do
subject
@ -64,7 +51,7 @@ describe Champs::PieceJustificativeController, type: :controller do
subject
expect(response.status).to eq(422)
expect(response.header['Content-Type']).to include('application/json')
expect(response.parsed_body).to eq({ 'errors' => ['La pièce justificative nest pas dun type accepté'] })
expect(response.parsed_body).to eq({ 'errors' => ['Le champ « Piece justificative file » nest pas dun type accepté'] })
end
end
end

View file

@ -3,14 +3,18 @@
describe Champs::RepetitionController, type: :controller do
describe '#remove' do
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :repetition, mandatory: true, children: [{ libelle: 'Nom' }, { type: :integer_number, libelle: 'Age' }] }]) }
let(:dossier) { create(:dossier, procedure: procedure) }
let(:dossier) { create(:dossier, procedure:) }
let(:repetition) { dossier.project_champs_public.find(&:repetition?) }
let(:row) { dossier.champs.find(&:row?) }
before { sign_in dossier.user }
it 'removes repetition' do
rows, repetitions = dossier.champs.partition(&:child?)
repetition = repetitions.first
expect { delete :remove, params: { dossier_id: dossier, stable_id: repetition.stable_id, row_id: rows.first.row_id }, format: :turbo_stream }
.to change { dossier.reload.champs.size }.from(3).to(1)
subject { delete :remove, params: { dossier_id: dossier, stable_id: repetition.stable_id, row_id: row.row_id }, format: :turbo_stream }
context 'removes repetition' do
it { expect { subject }.not_to change { dossier.reload.champs.size } }
it { expect { subject }.to change { dossier.reload; dossier.project_champs_public.find(&:repetition?).row_ids.size }.from(1).to(0) }
it { expect { subject }.to change { row.reload.discarded_at }.from(nil).to(Time) }
end
end
end

View file

@ -1002,10 +1002,11 @@ describe Instructeurs::DossiersController, type: :controller do
let(:another_instructeur) { create(:instructeur) }
let(:now) { Time.zone.parse('01/01/2100') }
let(:champ_repetition) { dossier.project_champs_private.fourth }
let(:champ_text) { champ_repetition.rows.first.first }
let(:champ_multiple_drop_down_list) { dossier.project_champs_private.first }
let(:champ_linked_drop_down_list) { dossier.project_champs_private.second }
let(:champ_datetime) { dossier.project_champs_private.third }
let(:champ_repetition) { dossier.project_champs_private.fourth }
let(:champ_drop_down_list) { dossier.project_champs_private.fifth }
context 'when no invalid champs_public' do
@ -1015,12 +1016,12 @@ describe Instructeurs::DossiersController, type: :controller do
another_instructeur.follow(dossier)
Timecop.freeze(now)
patch :update_annotations, params: params, format: :turbo_stream
dossier.reload
champ_multiple_drop_down_list.reload
champ_linked_drop_down_list.reload
champ_datetime.reload
champ_repetition.reload
champ_drop_down_list.reload
champ_text.reload
end
after do
@ -1059,9 +1060,9 @@ describe Instructeurs::DossiersController, type: :controller do
expect(champ_linked_drop_down_list.primary_value).to eq('primary')
expect(champ_linked_drop_down_list.secondary_value).to eq('secondary')
expect(champ_datetime.value).to eq(Time.zone.parse('2019-12-21T13:17:00').iso8601)
expect(champ_repetition.rows.first.first.value).to eq('text')
expect(champ_text.value).to eq('text')
expect(champ_drop_down_list.value).to eq('other value')
expect(dossier.reload.last_champ_private_updated_at).to eq(now)
expect(dossier.last_champ_private_updated_at).to eq(now)
expect(response).to have_http_status(200)
assert_enqueued_jobs(1, only: DossierIndexSearchTermsJob)
}

View file

@ -2,7 +2,8 @@
describe Users::CommencerController, type: :controller do
let(:user) { create(:user) }
let(:published_procedure) { create(:procedure, :for_individual, :published) }
let(:published_procedure) { create(:procedure, :for_individual, :published, types_de_champ_public:) }
let(:types_de_champ_public) { [] }
let(:draft_procedure) { create(:procedure, :with_path) }
describe '#commencer' do
@ -160,7 +161,8 @@ describe Users::CommencerController, type: :controller do
end
context 'when a dossier is being prefilled by GET' do
let(:type_de_champ_text) { create(:type_de_champ_text, procedure: published_procedure) }
let(:types_de_champ_public) { [{}] }
let(:type_de_champ_text) { published_procedure.published_revision.types_de_champ.first }
let(:path) { published_procedure.path }
let(:user) { create(:user) }

View file

@ -594,11 +594,11 @@ describe Users::DossiersController, type: :controller do
let(:dossier) { create(:dossier, :en_construction, :with_populated_champs, procedure:, user:) }
let(:types_de_champ_public) { [{ type: :repetition, libelle: 'repetition', children: [{ type: :text, libelle: 'child' }] }] }
let(:editing_fork) { dossier.owner_editing_fork }
let(:champ_repetition) { editing_fork.champs.find(&:repetition?) }
let(:champ_repetition) { editing_fork.project_champs_public.find(&:repetition?) }
before do
editing_fork
procedure.draft_revision.remove_type_de_champ(editing_fork.champs.find(&:repetition?).stable_id)
procedure.draft_revision.remove_type_de_champ(champ_repetition.stable_id)
procedure.publish_revision!
editing_fork.reload
@ -611,7 +611,7 @@ describe Users::DossiersController, type: :controller do
context 'when dossier was already submitted' do
before do
expect_any_instance_of(Dossier).to receive(:remove_piece_justificative_file_not_visible!)
expect_any_instance_of(Dossier).to receive(:remove_not_visible_or_empty_champs!)
post :submit_en_construction, params: payload
end

View file

@ -55,7 +55,8 @@ RSpec.describe Mutations::DossierModifierAnnotation, type: :graphql do
},
errors: nil
})
expect(annotation.reload.row_ids.size).to eq(3)
dossier.reload
expect(annotation.row_ids.size).to eq(3)
end
end

View file

@ -15,7 +15,7 @@ describe 'Dossier::Recovery::LifeCycle' do
let(:geo_area) { build(:geo_area, :selection_utilisateur, :polygon) }
let(:fp) { Rails.root.join('spec', 'fixtures', 'export.dump') }
let(:dossier) do
d = create(:dossier, procedure:)
d = create(:dossier, :with_populated_champs, procedure:)
repetition(d).add_row(updated_by: 'test')
pj_champ(d).piece_justificative_file.attach(some_file)
@ -49,7 +49,7 @@ describe 'Dossier::Recovery::LifeCycle' do
d
end
def repetition(d) = d.champs.find_by(type: "Champs::RepetitionChamp")
def repetition(d) = d.project_champs_public.find(&:repetition?)
def pj_champ(d) = d.champs.find_by(type: "Champs::PieceJustificativeChamp")
def carte(d) = d.champs.find_by(type: "Champs::CarteChamp")
def siret(d) = d.champs.find_by(type: "Champs::SiretChamp")
@ -83,7 +83,7 @@ describe 'Dossier::Recovery::LifeCycle' do
expect(reloaded_dossier.champs.count).not_to be(0)
expect(repetition(reloaded_dossier).rows.flatten.map(&:type)).to match_array(["Champs::PieceJustificativeChamp"])
expect(repetition(reloaded_dossier).rows.flatten.map(&:type)).to match_array(["Champs::PieceJustificativeChamp", "Champs::PieceJustificativeChamp", "Champs::PieceJustificativeChamp"])
expect(pj_champ(reloaded_dossier).piece_justificative_file).to be_attached
expect(carte(reloaded_dossier).geo_areas).to be_present

View file

@ -15,7 +15,7 @@ describe ChampPresentations::RepetitionPresentation do
}
let(:dossier) { create(:dossier, procedure:) }
let(:champ_repetition) { dossier.champs.find(&:repetition?) }
let(:champ_repetition) { dossier.project_champs_public.first }
before do
champ_repetition.add_row(updated_by: 'test')
@ -23,15 +23,15 @@ describe ChampPresentations::RepetitionPresentation do
row1, row2, row3 = champ_repetition.rows
nom, stars = row1
nom.update(value: "ruby")
stars.update(value: 5)
champ_for_update(nom).update(value: "ruby")
champ_for_update(stars).update(value: 5)
nom = row2.first
nom.update(value: "js")
champ_for_update(nom).update(value: "js")
nom, stars = row3
nom.update(value: "rust")
stars.update(value: 4)
champ_for_update(nom).update(value: "rust")
champ_for_update(stars).update(value: 4)
end
let(:representation) { described_class.new(libelle, champ_repetition.rows) }

View file

@ -58,7 +58,7 @@ describe Champ do
context 'when repetition not blank' do
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :repetition, children: [{ type: :text }] }]) }
let(:dossier) { create(:dossier, :with_populated_champs, procedure:) }
let(:champ) { dossier.champs.find(&:repetition?) }
let(:champ) { dossier.project_champs_public.find(&:repetition?) }
it { expect(champ.blank?).to be(false) }
end
@ -108,11 +108,10 @@ describe Champ do
let(:dossier) { create(:dossier, procedure: procedure) }
let(:public_champ) { dossier.project_champs_public.first }
let(:private_champ) { dossier.project_champs_private.first }
let(:champ_in_repetition) { dossier.project_champs_public.find(&:repetition?).champs.first }
let(:standalone_champ) { build(:champ, type_de_champ: build(:type_de_champ), dossier: build(:dossier)) }
let(:public_sections) { dossier.project_champs_public.filter(&:header_section?) }
let(:private_sections) { dossier.project_champs_private.filter(&:header_section?) }
let(:sections_in_repetition) { dossier.champs.filter(&:child?).filter(&:header_section?) }
let(:sections_in_repetition) { dossier.project_champs_public.find(&:repetition?).rows.flatten.filter(&:header_section?) }
it 'returns the sibling sections of a champ' do
expect(public_sections).not_to be_empty

View file

@ -11,11 +11,11 @@ describe Champs::RepetitionChamp do
])
}
let(:dossier) { create(:dossier, procedure:) }
let(:champ) { dossier.champs.find(&:repetition?) }
let(:champ) { dossier.project_champs_public.find(&:repetition?) }
describe "#for_tag" do
before do
champ.rows[0][0].update(value: "rb")
champ_for_update(champ.rows.first.first).update(value: "rb")
end
it "can render as string" do

View file

@ -237,11 +237,11 @@ describe TagsSubstitutionConcern, type: :model do
repetition.add_row(updated_by: 'test')
paul_champs, pierre_champs = repetition.rows
paul_champs.first.update(value: 'Paul')
paul_champs.last.update(value: 'Chavard')
champ_for_update(paul_champs.first).update(value: 'Paul')
champ_for_update(paul_champs.last).update(value: 'Chavard')
pierre_champs.first.update(value: 'Pierre')
pierre_champs.last.update(value: 'de La Morinerie')
champ_for_update(pierre_champs.first).update(value: 'Pierre')
champ_for_update(pierre_champs.last).update(value: 'de La Morinerie')
end
it { is_expected.to eq("Répétition\n\nNom : Paul\nPrénom : Chavard\n\nNom : Pierre\nPrénom : de La Morinerie") }
@ -258,7 +258,7 @@ describe TagsSubstitutionConcern, type: :model do
context 'and the champ has a primary value' do
before do
dossier.champs.find_by(stable_id: type_de_champ.stable_id).update(primary_value: 'primo')
dossier.champ_for_update(type_de_champ, nil, updated_by: 'test').update(primary_value: 'primo')
dossier.reload
end
@ -266,7 +266,7 @@ describe TagsSubstitutionConcern, type: :model do
context 'and the champ has a secondary value' do
before do
dossier.champs.find_by(stable_id: type_de_champ.stable_id).update(secondary_value: 'secundo')
dossier.champ_for_update(type_de_champ, nil, updated_by: 'test').update(secondary_value: 'secundo')
dossier.reload
end
@ -481,7 +481,7 @@ describe TagsSubstitutionConcern, type: :model do
before do
draft_type_de_champ.update(libelle: 'mon nouveau libellé')
dossier.project_champs_public.first.update(value: 'valeur')
procedure.update!(draft_revision: procedure.create_new_revision, published_revision: procedure.draft_revision)
procedure.publish_revision!
end
context "when using the champ's original label" do

View file

@ -29,7 +29,7 @@ describe DossierPreloader do
expect(subject.changed?).to be false
expect(first_child.type).to eq('Champs::TextChamp')
expect(repetition.id).not_to eq(first_child.id)
expect(repetition).not_to eq(first_child)
expect(subject.champs.first.dossier).to eq(subject)
expect(subject.champs.find(&:public?).dossier).to eq(subject)
expect(subject.project_champs_public.first.dossier).to eq(subject)
@ -40,7 +40,7 @@ describe DossierPreloader do
expect(subject.champs.find(&:public?).conditional?).to eq(false)
expect(subject.project_champs_public.first.conditional?).to eq(false)
expect(repetition.rows.first.first).to eq(first_child)
expect(repetition.rows.first.first.public_id).to eq(first_child.public_id)
expect(repetition_optional.row_ids).to be_empty
end

View file

@ -1984,13 +1984,12 @@ describe Dossier, type: :model do
context 'with integer_number' do
let(:procedure) { create(:procedure, :published, types_de_champ_public: [{ type: :integer_number, libelle: 'c1' }]) }
let(:dossier) { create(:dossier, :with_populated_champs, procedure:) }
let(:integer_number_type_de_champ) { procedure.active_revision.types_de_champ_public.find { |type_de_champ| type_de_champ.type_champ == TypeDeChamp.type_champs.fetch(:integer_number) } }
let(:integer_number_type_de_champ) { procedure.active_revision.types_de_champ_public.find(&:integer_number?) }
it 'give me back my decimal number' do
dossier
expect {
integer_number_type_de_champ.update(type_champ: :decimal_number)
procedure.update(published_revision: procedure.draft_revision, draft_revision: procedure.create_new_revision)
}.to change { dossier.reload.champ_values_for_export(procedure.all_revisions_types_de_champ.not_repetition.to_a, format: :xlsx) }
.from([["c1", 42]]).to([["c1", 42.0]])
end
@ -2030,7 +2029,7 @@ describe Dossier, type: :model do
procedure.draft_revision.find_and_ensure_exclusive_use(yes_no_type_de_champ.stable_id).update(libelle: 'Updated yes/no')
procedure.draft_revision.find_and_ensure_exclusive_use(commune_type_de_champ.stable_id).update(libelle: 'Commune de naissance')
procedure.draft_revision.find_and_ensure_exclusive_use(repetition_type_de_champ.stable_id).update(libelle: 'Repetition')
procedure.update(published_revision: procedure.draft_revision, draft_revision: procedure.create_new_revision)
procedure.publish_revision!
dossier.reload
procedure.reload
end

View file

@ -3,14 +3,14 @@
RSpec.describe TypesDeChamp::PrefillRepetitionTypeDeChamp, type: :model do
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :repetition, children: [{}, { type: :integer_number }, { type: :regions }] }]) }
let(:dossier) { create(:dossier, procedure: procedure) }
let(:champ) { dossier.project_champs_public.first }
let(:type_de_champ) { champ.type_de_champ }
let(:champ) { dossier.champs.first }
let(:prefillable_subchamps) { TypesDeChamp::PrefillRepetitionTypeDeChamp.new(type_de_champ, procedure.active_revision).send(:prefillable_subchamps) }
let(:text_repetition) { prefillable_subchamps.first }
let(:integer_repetition) { prefillable_subchamps.second }
let(:region_repetition) { prefillable_subchamps.third }
let(:text_repetition_champs) { dossier.champs.where(stable_id: text_repetition.stable_id) }
let(:integer_repetition_champs) { dossier.champs.where(stable_id: integer_repetition.stable_id) }
let(:text_repetition_champs) { champ.rows.flat_map(&:first) }
let(:integer_repetition_champs) { champ.rows.flat_map(&:second) }
describe 'ancestors' do
subject { described_class.build(type_de_champ, procedure.active_revision) }

View file

@ -125,6 +125,13 @@ RSpec.configure do |config|
end
end
module SpecHelpers
def champ_for_update(champ)
champ.dossier.champ_for_update(champ.type_de_champ, champ.row_id, updated_by: 'test')
end
end
config.include SpecHelpers
config.include ActiveSupport::Testing::TimeHelpers
config.include Shoulda::Matchers::ActiveRecord, type: :model
config.include Shoulda::Matchers::ActiveModel, type: :model

View file

@ -10,8 +10,8 @@ describe PiecesJustificativesService do
let(:pj_service) { PiecesJustificativesService.new(user_profile:, export_template:) }
let(:user_profile) { build(:administrateur) }
def pj_champ(d) = d.project_champs_public.find { _1.type == 'Champs::PieceJustificativeChamp' }
def repetition(d) = d.champs.find_by(type: "Champs::RepetitionChamp")
def pj_champ(d) = d.project_champs_public.find(&:piece_justificative?)
def repetition(d) = d.project_champs_public.find(&:repetition?)
def attachments(champ) = champ.piece_justificative_file.attachments
before { attach_file_to_champ(pj_champ(witness)) }
@ -52,21 +52,20 @@ describe PiecesJustificativesService do
end
context 'with a repetition' do
let(:first_champ) { repetition(dossier).rows.first.first }
let(:second_champ) { repetition(dossier).rows.second.first }
let(:first_champ) { champ_for_update(repetition(dossier).rows.first.first) }
let(:second_champ) { champ_for_update(repetition(dossier).rows.second.first) }
before do
repetition(dossier).add_row(updated_by: 'test')
attach_file_to_champ(first_champ)
attach_file_to_champ(first_champ)
repetition(dossier).add_row(updated_by: 'test')
attach_file_to_champ(first_champ)
attach_file_to_champ(first_champ)
attach_file_to_champ(second_champ)
end
it do
first_child_attachments = attachments(repetition(dossier).rows.first.first)
second_child_attachments = attachments(repetition(dossier).rows.second.first)
first_child_attachments = attachments(first_champ)
second_child_attachments = attachments(second_champ)
expect(export_template).to receive(:attachment_path)
.with(dossier, first_child_attachments.first, index: 0, row_index: 0, champ: first_champ)
@ -103,7 +102,7 @@ describe PiecesJustificativesService do
let(:user_profile) { build(:administrateur) }
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :piece_justificative }]) }
let(:witness) { create(:dossier, procedure: procedure) }
def pj_champ(d) = d.project_champs_public.find { |c| c.type == 'Champs::PieceJustificativeChamp' }
def pj_champ(d) = d.project_champs_public.find(&:piece_justificative?)
context 'with a single attachment' do
before do
@ -144,7 +143,7 @@ describe PiecesJustificativesService do
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :titre_identite }]) }
let(:dossier) { create(:dossier, procedure: procedure) }
let(:champ_identite) { dossier.project_champs_public.find { |c| c.type == 'Champs::TitreIdentiteChamp' } }
let(:champ_identite) { dossier.project_champs_public.find(&:titre_identite?) }
before { attach_file_to_champ(champ_identite) }
@ -261,7 +260,7 @@ describe PiecesJustificativesService do
let(:witness) { create(:dossier, procedure: procedure) }
let!(:private_pj) { create(:type_de_champ_piece_justificative, procedure: procedure, private: true) }
def private_pj_champ(d) = d.project_champs_private.find { |c| c.type == 'Champs::PieceJustificativeChamp' }
def private_pj_champ(d) = d.project_champs_private.find(&:piece_justificative?)
before do
attach_file_to_champ(private_pj_champ(dossier))
@ -501,17 +500,14 @@ describe PiecesJustificativesService do
end
let(:procedure) { create(:procedure, types_de_champ_public:) }
let(:dossier_1) { create(:dossier, procedure:) }
let(:champs) { dossier_1.champs }
let(:dossier_1) { create(:dossier, :with_populated_champs, procedure:) }
let(:champs) { dossier_1.filled_champs }
def pj_champ(d) = d.project_champs_public.find { _1.type == 'Champs::PieceJustificativeChamp' }
def repetition(d, index:) = d.project_champs_public.filter(&:repetition?)[index]
subject { PiecesJustificativesService.new(user_profile:, export_template: nil).send(:compute_champ_id_row_index, champs) }
before do
pj_champ(dossier_1)
# repet_0 (stable_id: r0)
# # row_0
# # # pj_champ_0 (stable_id: 0)
@ -553,7 +549,9 @@ describe PiecesJustificativesService do
end
def attach_file_to_champ(champ, safe = true)
champ = champ_for_update(champ)
attach_file(champ.piece_justificative_file, safe)
champ.save!
end
def attach_file(attachable, safe = true)

View file

@ -7,8 +7,8 @@ describe ProcedureExportService do
let(:export_template) { create(:export_template, :enabled_pjs, groupe_instructeur: procedure.defaut_groupe_instructeur) }
let(:service) { ProcedureExportService.new(procedure, procedure.dossiers, instructeur, export_template) }
def pj_champ(d) = d.project_champs_public.find { _1.type == 'Champs::PieceJustificativeChamp' }
def repetition(d) = d.champs.find_by(type: "Champs::RepetitionChamp")
def pj_champ(d) = d.project_champs_public.find(&:piece_justificative?)
def repetition(d) = d.project_champs_public.find(&:repetition?)
def attachments(champ) = champ.piece_justificative_file.attachments
before do
@ -69,7 +69,9 @@ describe ProcedureExportService do
end
def attach_file_to_champ(champ, safe = true)
champ = champ_for_update(champ)
attach_file(champ.piece_justificative_file, safe)
champ.save!
end
def attach_file(attachable, safe = true)

View file

@ -171,7 +171,7 @@ describe 'The user', js: true do
wait_until { page.all(".row").size == 1 }
# removing a repetition means one child only, thus its button destroy is not visible
expect(page).to have_selector(".repetition .row:first-child .utils-repetition-required-destroy-button", count: 1, visible: false)
end.to change { Champ.count }
end.to change { Champ.where.not(discarded_at: nil).count }
end
let(:simple_procedure) {