Merge branch 'main' into fix/stored_query_issue
This commit is contained in:
commit
8a7cb3f1fe
301 changed files with 4456 additions and 1168 deletions
|
@ -103,7 +103,7 @@ RSpec.describe Attachment::EditComponent, type: :component do
|
|||
it 'displays the filename, but doesn’t allow to download the file' do
|
||||
expect(attachment.watermark_pending?).to be_truthy
|
||||
expect(subject).to have_text(filename)
|
||||
expect(subject).to have_link('Supprimer')
|
||||
expect(subject).to have_button('Supprimer')
|
||||
expect(subject).to have_no_link(text: filename) # don't match "Delete" link which also include filename in title attribute
|
||||
expect(subject).to have_text('Traitement en cours')
|
||||
end
|
||||
|
@ -152,8 +152,12 @@ RSpec.describe Attachment::EditComponent, type: :component do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when the file is scanned and safe' do
|
||||
context 'when the file is scanned, watermarked_at, and viewed as download and safe' do
|
||||
let(:kwargs) { { view_as: :download } }
|
||||
let(:virus_scan_result) { ActiveStorage::VirusScanner::SAFE }
|
||||
before do
|
||||
attachment.blob.touch(:watermarked_at)
|
||||
end
|
||||
|
||||
it 'allows to download the file' do
|
||||
expect(subject).to have_link(filename)
|
||||
|
|
|
@ -47,8 +47,8 @@ RSpec.describe Attachment::MultipleComponent, type: :component do
|
|||
end
|
||||
|
||||
it 'shows the Delete button by default' do
|
||||
expect(subject).to have_link(title: "Supprimer le fichier #{attached_file.attachments[0].filename}")
|
||||
expect(subject).to have_link(title: "Supprimer le fichier #{attached_file.attachments[1].filename}")
|
||||
expect(subject).to have_button(title: "Supprimer le fichier #{attached_file.attachments[0].filename}")
|
||||
expect(subject).to have_button(title: "Supprimer le fichier #{attached_file.attachments[1].filename}")
|
||||
end
|
||||
|
||||
it 'renders a form field for uploading a new file' do
|
||||
|
|
73
spec/components/simple_format_component_spec.rb
Normal file
73
spec/components/simple_format_component_spec.rb
Normal file
|
@ -0,0 +1,73 @@
|
|||
describe SimpleFormatComponent, type: :component do
|
||||
let(:allow_a) { false }
|
||||
before { render_inline(described_class.new(text, allow_a: allow_a)) }
|
||||
|
||||
context 'one line' do
|
||||
let(:text) do
|
||||
"1er paragraphe"
|
||||
end
|
||||
it { expect(page).to have_selector("p", count: 1, text: text) }
|
||||
end
|
||||
|
||||
context 'one with leading spaces' do
|
||||
let(:text) do
|
||||
<<-TEXT
|
||||
1er paragraphe
|
||||
TEXT
|
||||
end
|
||||
it { expect(page).to have_selector("p", count: 1, text: text.strip) }
|
||||
end
|
||||
|
||||
context 'two lines' do
|
||||
let(:text) do
|
||||
<<~TEXT
|
||||
1er paragraphe
|
||||
2eme paragraphe
|
||||
TEXT
|
||||
end
|
||||
|
||||
it { expect(page).to have_selector("p", count: 2) }
|
||||
it { text.split("\n").map(&:strip).map { expect(page).to have_text(_1) } }
|
||||
end
|
||||
|
||||
context 'unordered list items' do
|
||||
let(:text) do
|
||||
<<~TEXT
|
||||
- 1er paragraphe
|
||||
- paragraphe
|
||||
TEXT
|
||||
end
|
||||
|
||||
it { expect(page).to have_selector("ul", count: 1) }
|
||||
it { expect(page).to have_selector("li", count: 2) }
|
||||
end
|
||||
|
||||
context 'ordered list items' do
|
||||
let(:text) do
|
||||
<<~TEXT
|
||||
1. 1er paragraphe
|
||||
2. paragraphe
|
||||
TEXT
|
||||
end
|
||||
|
||||
it { expect(page).to have_selector("ol", count: 1) }
|
||||
it { expect(page).to have_selector("li", count: 2) }
|
||||
end
|
||||
|
||||
context 'auto-link' do
|
||||
let(:text) do
|
||||
<<~TEXT
|
||||
bonjour https://www.demarches-simplifiees.fr
|
||||
TEXT
|
||||
end
|
||||
|
||||
context 'enabled' do
|
||||
let(:allow_a) { true }
|
||||
it { expect(page).to have_selector("a") }
|
||||
end
|
||||
|
||||
context 'disabled' do
|
||||
it { expect(page).not_to have_selector("a") }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -268,11 +268,22 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
|
|||
|
||||
context 'of a news instructeurs' do
|
||||
let(:new_instructeur_emails) { ['new_i1@mail.com', 'new_i2@mail.com'] }
|
||||
before { do_request }
|
||||
before do
|
||||
allow(GroupeInstructeurMailer).to receive(:notify_added_instructeurs)
|
||||
.and_return(double(deliver_later: true))
|
||||
do_request
|
||||
end
|
||||
it { expect(gi_1_2.instructeurs.pluck(:email)).to include(*new_instructeur_emails) }
|
||||
it { expect(flash.notice).to be_present }
|
||||
it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) }
|
||||
it { expect(procedure.routing_enabled?).to be_truthy }
|
||||
it "calls GroupeInstructeurMailer with the right params" do
|
||||
expect(GroupeInstructeurMailer).to have_received(:notify_added_instructeurs).with(
|
||||
gi_1_2,
|
||||
gi_1_2.instructeurs.last(2),
|
||||
admin.email
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'of an instructeur already in the group' do
|
||||
|
@ -320,11 +331,22 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
|
|||
end
|
||||
|
||||
context 'when there are many instructeurs' do
|
||||
before { remove_instructeur(admin.instructeur) }
|
||||
before do
|
||||
allow(GroupeInstructeurMailer).to receive(:notify_removed_instructeur)
|
||||
.and_return(double(deliver_later: true))
|
||||
remove_instructeur(admin.instructeur)
|
||||
end
|
||||
|
||||
it { expect(gi_1_1.instructeurs).to include(instructeur) }
|
||||
it { expect(gi_1_1.reload.instructeurs.count).to eq(1) }
|
||||
it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_1)) }
|
||||
it "calls GroupeInstructeurMailer with the right groupe and instructeur" do
|
||||
expect(GroupeInstructeurMailer).to have_received(:notify_removed_instructeur).with(
|
||||
gi_1_1,
|
||||
admin.instructeur,
|
||||
admin.email
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is only one instructeur' do
|
||||
|
@ -383,6 +405,17 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
|
|||
it { expect(flash.alert).to eq("Import terminé. Cependant les emails suivants ne sont pas pris en compte: kara") }
|
||||
end
|
||||
|
||||
context 'when the csv file has only one column' do
|
||||
let(:csv_file) { fixture_file_upload('spec/fixtures/files/valid-instructeurs-file.csv', 'text/csv') }
|
||||
|
||||
before { subject }
|
||||
|
||||
it { expect { subject }.not_to raise_error }
|
||||
it { expect(response.status).to eq(302) }
|
||||
it { expect(flash.alert).to be_present }
|
||||
it { expect(flash.alert).to eq("Importation impossible, veuillez importer un csv <a href=\"/csv/#{I18n.locale}/import-groupe-test.csv\">suivant ce modèle</a>") }
|
||||
end
|
||||
|
||||
context 'when the file content type is application/vnd.ms-excel' do
|
||||
let(:csv_file) { fixture_file_upload('spec/fixtures/files/groupe_avec_caracteres_speciaux.csv', "application/vnd.ms-excel") }
|
||||
|
||||
|
@ -395,11 +428,16 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
|
|||
context 'when the content of csv contains special characters' do
|
||||
let(:csv_file) { fixture_file_upload('spec/fixtures/files/groupe_avec_caracteres_speciaux.csv', 'text/csv') }
|
||||
|
||||
before { subject }
|
||||
before do
|
||||
allow(GroupeInstructeurMailer).to receive(:notify_added_instructeurs)
|
||||
.and_return(double(deliver_later: true))
|
||||
subject
|
||||
end
|
||||
|
||||
it { expect(procedure.groupe_instructeurs.pluck(:label)).to match_array(["Auvergne-Rhône-Alpes", "Vendée", "défaut"]) }
|
||||
it { expect(flash.notice).to be_present }
|
||||
it { expect(flash.notice).to eq("La liste des instructeurs a été importée avec succès") }
|
||||
it { expect(GroupeInstructeurMailer).to have_received(:notify_added_instructeurs).twice }
|
||||
end
|
||||
|
||||
context 'when the csv file length is more than 1 mo' do
|
||||
|
@ -443,6 +481,76 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#add_instructeurs_via_csv_file' do
|
||||
let(:procedure_non_routee) { create(:procedure, :published, :for_individual, administrateurs: [admin]) }
|
||||
|
||||
subject do
|
||||
post :import, params: { procedure_id: procedure_non_routee.id, instructeurs_csv_file: csv_file }
|
||||
end
|
||||
|
||||
context 'when the csv file is less than 1 mo and content type text/csv' do
|
||||
let(:csv_file) { fixture_file_upload('spec/fixtures/files/instructeurs-file.csv', 'text/csv') }
|
||||
|
||||
before do
|
||||
allow(GroupeInstructeurMailer).to receive(:notify_added_instructeurs)
|
||||
.and_return(double(deliver_later: true))
|
||||
subject
|
||||
end
|
||||
|
||||
it { expect(response.status).to eq(302) }
|
||||
it { expect(procedure_non_routee.instructeurs.pluck(:email)).to match_array(["kara@beta-gouv.fr", "philippe@mail.com", "lisa@gouv.fr"]) }
|
||||
it { expect(flash.alert).to be_present }
|
||||
it { expect(flash.alert).to eq("Import terminé. Cependant les emails suivants ne sont pas pris en compte: eric") }
|
||||
it "calls GroupeInstructeurMailer" do
|
||||
expect(GroupeInstructeurMailer).to have_received(:notify_added_instructeurs).with(
|
||||
procedure_non_routee.defaut_groupe_instructeur,
|
||||
any_args,
|
||||
admin.email
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the csv file has more than one column' do
|
||||
let(:csv_file) { fixture_file_upload('spec/fixtures/files/groupe-instructeur.csv', 'text/csv') }
|
||||
|
||||
before { subject }
|
||||
|
||||
it { expect(response.status).to eq(302) }
|
||||
it { expect(flash.alert).to be_present }
|
||||
it { expect(flash.alert).to eq("Importation impossible, veuillez importer un csv <a href=\"/csv/import-instructeurs-test.csv\">suivant ce modèle</a>") }
|
||||
end
|
||||
|
||||
context 'when the file content type is application/vnd.ms-excel' do
|
||||
let(:csv_file) { fixture_file_upload('spec/fixtures/files/valid-instructeurs-file.csv', "application/vnd.ms-excel") }
|
||||
|
||||
before { subject }
|
||||
it { expect(procedure_non_routee.instructeurs.pluck(:email)).to match_array(["kara@beta-gouv.fr", "philippe@mail.com", "lisa@gouv.fr"]) }
|
||||
it { expect(flash.notice).to be_present }
|
||||
it { expect(flash.notice).to eq("La liste des instructeurs a été importée avec succès") }
|
||||
end
|
||||
|
||||
context 'when the csv file length is more than 1 mo' do
|
||||
let(:csv_file) { fixture_file_upload('spec/fixtures/files/groupe-instructeur.csv', 'text/csv') }
|
||||
|
||||
before do
|
||||
allow_any_instance_of(ActionDispatch::Http::UploadedFile).to receive(:size).and_return(3.megabytes)
|
||||
subject
|
||||
end
|
||||
|
||||
it { expect(flash.alert).to be_present }
|
||||
it { expect(flash.alert).to eq("Importation impossible : le poids du fichier est supérieur à 1 Mo") }
|
||||
end
|
||||
|
||||
context 'when the file content type is not accepted' do
|
||||
let(:csv_file) { fixture_file_upload('spec/fixtures/files/french-flag.gif', 'image/gif') }
|
||||
|
||||
before { subject }
|
||||
|
||||
it { expect(flash.alert).to be_present }
|
||||
it { expect(flash.alert).to eq("Importation impossible : veuillez importer un fichier CSV") }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#export_groupe_instructeurs' do
|
||||
let(:procedure) { create(:procedure, :published) }
|
||||
let(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 1 2') }
|
||||
|
|
|
@ -132,6 +132,16 @@ describe Administrateurs::ProceduresController, type: :controller do
|
|||
expect(assigns(:procedures).any? { |p| p.id == procedure2.id }).to be_truthy
|
||||
expect(assigns(:procedures).any? { |p| p.id == procedure1.id }).to be_falsey
|
||||
end
|
||||
|
||||
context "without zones" do
|
||||
let!(:procedure) { create(:procedure, :published, zones: []) }
|
||||
subject { get :all }
|
||||
|
||||
it 'displays procedures without zones' do
|
||||
subject
|
||||
expect(assigns(:procedures).any? { |p| p.id == procedure.id }).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'for specific status' do
|
||||
|
|
|
@ -50,8 +50,8 @@ RSpec.describe API::Public::V1::DossiersController, type: :controller do
|
|||
let(:params) {
|
||||
{
|
||||
id: procedure.id,
|
||||
"champ_#{type_de_champ_1.to_typed_id}" => value_1,
|
||||
"champ_#{type_de_champ_2.to_typed_id}" => value_2
|
||||
"champ_#{type_de_champ_1.to_typed_id_for_query}" => value_1,
|
||||
"champ_#{type_de_champ_2.to_typed_id_for_query}" => value_2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,6 +130,74 @@ RSpec.describe API::Public::V1::DossiersController, type: :controller do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#index' do
|
||||
let(:procedure) { dossier.procedure }
|
||||
let(:dossier) { create(:dossier, prefilled: true, user: nil) }
|
||||
let(:prefill_token) { dossier.prefill_token }
|
||||
let(:params) { { id: procedure.id, prefill_token: } }
|
||||
|
||||
subject(:create_request) do
|
||||
request.headers["Content-Type"] = "application/json"
|
||||
get :index, params:
|
||||
end
|
||||
|
||||
let(:body) { JSON.parse(response.body).map(&:deep_symbolize_keys) }
|
||||
|
||||
before { create_request }
|
||||
|
||||
context 'not found' do
|
||||
let(:prefill_token) { 'invalid_token' }
|
||||
it 'should respond with and empty array' do
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(body).to eq([])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when dossier prefilled' do
|
||||
it 'should respond with dossier state' do
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(body.first[:state]).to eq('prefilled')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when dossier brouillon' do
|
||||
let(:dossier) { create(:dossier, prefilled: true) }
|
||||
it 'should respond with dossier state' do
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(body.first[:state]).to eq('brouillon')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when dossier en_construction' do
|
||||
let(:dossier) { create(:dossier, :en_construction, prefilled: true) }
|
||||
it 'should respond with dossier state' do
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(body.first[:state]).to eq('en_construction')
|
||||
expect(body.first[:submitted_at]).to eq(dossier.depose_at.iso8601)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with multiple tokens' do
|
||||
let(:dossier) { create(:dossier, prefilled: true, user: nil) }
|
||||
let(:other_dossier) { create(:dossier, prefilled: true, user: nil, procedure:) }
|
||||
let(:prefill_token) { [dossier.prefill_token, other_dossier.prefill_token] }
|
||||
|
||||
it 'should respond with dossiers state' do
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(body.map { _1[:dossier_number] }).to match_array([dossier.id, other_dossier.id])
|
||||
end
|
||||
|
||||
context 'comma separated tokens' do
|
||||
let(:prefill_token) { [dossier.prefill_token, other_dossier.prefill_token].join(',') }
|
||||
|
||||
it 'should respond with dossiers state' do
|
||||
expect(response).to have_http_status(:ok)
|
||||
expect(body.map { _1[:dossier_number] }).to match_array([dossier.id, other_dossier.id])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_champ_by_stable_id(dossier, stable_id)
|
||||
|
|
|
@ -4,6 +4,13 @@ describe API::V1::DossiersController do
|
|||
let(:procedure) { create(:procedure, :with_type_de_champ, :with_type_de_champ_private, administrateur: admin) }
|
||||
let(:wrong_procedure) { create(:procedure) }
|
||||
|
||||
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
|
||||
|
||||
before do
|
||||
allow(Rails).to receive(:cache).and_return(memory_store)
|
||||
Rails.cache.clear
|
||||
end
|
||||
|
||||
it { expect(described_class).to be < APIController }
|
||||
|
||||
describe 'GET index (with bearer token)' do
|
||||
|
@ -258,7 +265,7 @@ describe API::V1::DossiersController do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'departement' do
|
||||
describe 'departement', vcr: { cassette_name: 'api_geo_departements' } do
|
||||
let(:procedure) { create(:procedure, :with_departement, administrateur: admin) }
|
||||
let(:dossier) { create(:dossier, :en_construction, :with_populated_champs, procedure: procedure) }
|
||||
|
||||
|
@ -279,9 +286,9 @@ describe API::V1::DossiersController do
|
|||
it 'should have rows' do
|
||||
expect(subject.size).to eq(2)
|
||||
expect(subject[0][:id]).to eq(1)
|
||||
expect(subject[0][:champs].size).to eq(1)
|
||||
expect(subject[0][:champs].map { |c| c[:value] }).to eq(['text'])
|
||||
expect(subject[0][:champs].map { |c| c[:type_de_champ][:type_champ] }).to eq(['text'])
|
||||
expect(subject[0][:champs].size).to eq(2)
|
||||
expect(subject[0][:champs].map { |c| c[:value] }).to eq(['text', 42])
|
||||
expect(subject[0][:champs].map { |c| c[:type_de_champ][:type_champ] }).to eq(['text', 'integer_number'])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,7 +42,6 @@ describe API::V2::GraphqlController do
|
|||
allow(Rails).to receive(:cache).and_return(memory_store)
|
||||
Rails.cache.clear
|
||||
|
||||
allow(APIGeoService).to receive(:departement_name).with('01').and_return('Ain')
|
||||
instructeur.assign_to_procedure(procedure)
|
||||
end
|
||||
|
||||
|
@ -397,7 +396,7 @@ describe API::V2::GraphqlController do
|
|||
dossier
|
||||
end
|
||||
|
||||
context "for individual", vcr: { cassette_name: 'api_geo_regions' } do
|
||||
context "for individual", vcr: { cassette_name: 'api_geo_all' } do
|
||||
let(:procedure) { create(:procedure, :published, :for_individual, :with_service, :with_all_champs, :with_all_annotations, administrateurs: [admin]) }
|
||||
let(:query) do
|
||||
"{
|
||||
|
|
|
@ -138,6 +138,7 @@ describe API::V2::GraphqlController do
|
|||
it {
|
||||
expect(gql_errors).to be_nil
|
||||
expect(gql_data[:demarcheDescriptor][:id]).to eq(procedure.to_typed_id)
|
||||
expect(gql_data[:demarcheDescriptor][:demarcheUrl]).to match("commencer/#{procedure.path}")
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -37,10 +37,8 @@ describe Champs::RNAController, type: :controller do
|
|||
|
||||
subject! { get :show, params: params, format: :turbo_stream }
|
||||
|
||||
it 'clears the data and value on the model' do
|
||||
champ.reload
|
||||
expect(champ.data).to eq({})
|
||||
expect(champ.value).to eq("")
|
||||
it 'clears the data on the model' do
|
||||
expect(champ.reload.data).to be_nil
|
||||
end
|
||||
|
||||
it 'clears any information or error message' do
|
||||
|
@ -55,14 +53,12 @@ describe Champs::RNAController, type: :controller do
|
|||
|
||||
subject! { get :show, params: params, format: :turbo_stream }
|
||||
|
||||
it 'clears the data and value on the model' do
|
||||
champ.reload
|
||||
expect(champ.data).to be_nil
|
||||
expect(champ.value).to be_nil
|
||||
it 'clears the data on the model' do
|
||||
expect(champ.reload.data).to be_nil
|
||||
end
|
||||
|
||||
it 'displays a “RNA is invalid” error message' do
|
||||
expect(response.body).to include("Aucun établissement trouvé")
|
||||
expect(response.body).to include("Le numéro RNA doit commencer par un W majuscule suivi de 9 chiffres")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -75,7 +71,7 @@ describe Champs::RNAController, type: :controller do
|
|||
|
||||
it 'clears the data on the model' do
|
||||
champ.reload
|
||||
expect(champ.data).to eq({})
|
||||
expect(champ.data).to be_nil
|
||||
end
|
||||
|
||||
it 'displays a “RNA is invalid” error message' do
|
||||
|
@ -94,10 +90,8 @@ describe Champs::RNAController, type: :controller do
|
|||
|
||||
subject! { get :show, params: params, format: :turbo_stream }
|
||||
|
||||
it 'clears the data and value on the model' do
|
||||
champ.reload
|
||||
expect(champ.data).to be_nil
|
||||
expect(champ.value).to be_nil
|
||||
it 'clears the data on the model' do
|
||||
expect(champ.reload.data).to be_nil
|
||||
end
|
||||
|
||||
it 'displays a “API is unavailable” error message' do
|
||||
|
|
|
@ -31,6 +31,8 @@ describe Champs::SiretController, type: :controller do
|
|||
sign_in user
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}/)
|
||||
.to_return(status: api_etablissement_status, body: api_etablissement_body)
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siret[0..8]}/)
|
||||
.to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/entreprises.json'))
|
||||
allow_any_instance_of(APIEntrepriseToken).to receive(:roles)
|
||||
.and_return(["attestations_fiscales", "attestations_sociales", "bilans_entreprise_bdf"])
|
||||
allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(token_expired)
|
||||
|
@ -39,10 +41,8 @@ describe Champs::SiretController, type: :controller do
|
|||
context 'when the SIRET is empty' do
|
||||
subject! { get :show, params: params, format: :turbo_stream }
|
||||
|
||||
it 'clears the etablissement and SIRET on the model' do
|
||||
champ.reload
|
||||
expect(champ.etablissement).to be_nil
|
||||
expect(champ.value).to be_empty
|
||||
it 'clears the etablissement on the model' do
|
||||
expect(champ.reload.etablissement).to be_nil
|
||||
end
|
||||
|
||||
it 'clears any information or error message' do
|
||||
|
@ -50,15 +50,13 @@ describe Champs::SiretController, type: :controller do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when the SIRET is invalid' do
|
||||
context "when the SIRET is invalid because of it's length" do
|
||||
let(:siret) { '1234' }
|
||||
|
||||
subject! { get :show, params: params, format: :turbo_stream }
|
||||
|
||||
it 'clears the etablissement and SIRET on the model' do
|
||||
champ.reload
|
||||
expect(champ.etablissement).to be_nil
|
||||
expect(champ.value).to be_empty
|
||||
it 'clears the etablissement on the model' do
|
||||
expect(champ.reload.etablissement).to be_nil
|
||||
end
|
||||
|
||||
it 'displays a “SIRET is invalid” error message' do
|
||||
|
@ -66,6 +64,20 @@ describe Champs::SiretController, type: :controller do
|
|||
end
|
||||
end
|
||||
|
||||
context "when the SIRET is invalid because of it's checksum" do
|
||||
let(:siret) { '82812345600023' }
|
||||
|
||||
subject! { get :show, params: params, format: :turbo_stream }
|
||||
|
||||
it 'clears the etablissement on the model' do
|
||||
expect(champ.reload.etablissement).to be_nil
|
||||
end
|
||||
|
||||
it 'displays a “SIRET is invalid” error message' do
|
||||
expect(response.body).to include('Le format du numéro de SIRET est invalide.')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the API is unavailable due to network error' do
|
||||
let(:siret) { '82161143100015' }
|
||||
let(:api_etablissement_status) { 503 }
|
||||
|
@ -76,10 +88,8 @@ describe Champs::SiretController, type: :controller do
|
|||
|
||||
subject! { get :show, params: params, format: :turbo_stream }
|
||||
|
||||
it 'clears the etablissement and SIRET on the model' do
|
||||
champ.reload
|
||||
expect(champ.etablissement).to be_nil
|
||||
expect(champ.value).to be_empty
|
||||
it 'clears the etablissement on the model' do
|
||||
expect(champ.reload.etablissement).to be_nil
|
||||
end
|
||||
|
||||
it 'displays a “API is unavailable” error message' do
|
||||
|
@ -115,10 +125,8 @@ describe Champs::SiretController, type: :controller do
|
|||
|
||||
subject! { get :show, params: params, format: :turbo_stream }
|
||||
|
||||
it 'clears the etablissement and SIRET on the model' do
|
||||
champ.reload
|
||||
expect(champ.etablissement).to be_nil
|
||||
expect(champ.value).to be_empty
|
||||
it 'clears the etablissement on the model' do
|
||||
expect(champ.reload.etablissement).to be_nil
|
||||
end
|
||||
|
||||
it 'displays a “SIRET not found” error message' do
|
||||
|
|
|
@ -792,7 +792,7 @@ describe Instructeurs::DossiersController, type: :controller do
|
|||
champs_private_attributes: {
|
||||
'0': {
|
||||
id: champ_multiple_drop_down_list.id,
|
||||
value: ['', 'un', 'deux']
|
||||
value: ['', 'val1', 'val2']
|
||||
},
|
||||
'1': {
|
||||
id: champ_datetime.id,
|
||||
|
@ -813,7 +813,7 @@ describe Instructeurs::DossiersController, type: :controller do
|
|||
end
|
||||
|
||||
it {
|
||||
expect(champ_multiple_drop_down_list.value).to eq('["un", "deux"]')
|
||||
expect(champ_multiple_drop_down_list.value).to eq('["val1", "val2"]')
|
||||
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('2019-12-21T13:17:00+01:00')
|
||||
|
@ -839,7 +839,7 @@ describe Instructeurs::DossiersController, type: :controller do
|
|||
champs_public_attributes: {
|
||||
'0': {
|
||||
id: champ_multiple_drop_down_list.id,
|
||||
value: ['', 'un', 'deux']
|
||||
value: ['', 'val1', 'val2']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,7 @@ describe PasswordComplexityController, type: :controller do
|
|||
|
||||
it 'renders Javascript that updates the password complexity meter' do
|
||||
subject
|
||||
expect(response.body).to include('complexity-label')
|
||||
expect(response.body).to include('complexity-bar')
|
||||
expect(response.body).to include('Mot de passe vulnérable')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -67,24 +67,19 @@ describe PrefillDescriptionsController, type: :controller do
|
|||
it { expect(response).to render_template(:update) }
|
||||
|
||||
it "includes the prefill URL" do
|
||||
type_de_champ_value = I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")
|
||||
type_de_champ_to_add_value = I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ_to_add.type_champ}")
|
||||
expect(response.body).to include(commencer_path(path: procedure.path))
|
||||
expect(response.body).to include(
|
||||
{
|
||||
"champ_#{type_de_champ.to_typed_id}" => I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")
|
||||
}.to_query
|
||||
)
|
||||
expect(response.body).to include({
|
||||
"champ_#{type_de_champ_to_add.to_typed_id}" => I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ_to_add.type_champ}")
|
||||
}.to_query)
|
||||
expect(response.body).to include("champ_#{type_de_champ.to_typed_id_for_query}=#{type_de_champ_value}")
|
||||
expect(response.body).to include("champ_#{type_de_champ_to_add.to_typed_id_for_query}=#{type_de_champ_to_add_value}")
|
||||
end
|
||||
|
||||
it "includes the prefill query" do
|
||||
type_de_champ_value = I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")
|
||||
type_de_champ_to_add_value = I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ_to_add.type_champ}")
|
||||
|
||||
expect(response.body).to include(api_public_v1_dossiers_path(procedure))
|
||||
expect(response.body).to include(
|
||||
""champ_#{type_de_champ.to_typed_id}": "#{type_de_champ_value}", "champ_#{type_de_champ_to_add.to_typed_id}": "#{type_de_champ_to_add_value}""
|
||||
""champ_#{type_de_champ.to_typed_id_for_query}":"#{type_de_champ_value}","champ_#{type_de_champ_to_add.to_typed_id_for_query}":"#{type_de_champ_to_add_value}""
|
||||
)
|
||||
end
|
||||
end
|
||||
|
@ -96,13 +91,11 @@ describe PrefillDescriptionsController, type: :controller do
|
|||
it { expect(response).to render_template(:update) }
|
||||
|
||||
it "includes the prefill URL" do
|
||||
type_de_champ_value = I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")
|
||||
type_de_champ_to_remove_value = I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ_to_remove.type_champ}")
|
||||
expect(response.body).to include(commencer_path(path: procedure.path))
|
||||
expect(response.body).to include({
|
||||
"champ_#{type_de_champ.to_typed_id}" => I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")
|
||||
}.to_query)
|
||||
expect(response.body).not_to include({
|
||||
"champ_#{type_de_champ_to_remove.to_typed_id}" => I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ_to_remove.type_champ}")
|
||||
}.to_query)
|
||||
expect(response.body).to include("champ_#{type_de_champ.to_typed_id_for_query}=#{type_de_champ_value}")
|
||||
expect(response.body).not_to include("champ_#{type_de_champ_to_remove.to_typed_id_for_query}=#{type_de_champ_to_remove_value}")
|
||||
end
|
||||
|
||||
it "includes the prefill query" do
|
||||
|
@ -111,10 +104,10 @@ describe PrefillDescriptionsController, type: :controller do
|
|||
|
||||
expect(response.body).to include(api_public_v1_dossiers_path(procedure))
|
||||
expect(response.body).to include(
|
||||
""champ_#{type_de_champ.to_typed_id}": "#{type_de_champ_value}""
|
||||
""champ_#{type_de_champ.to_typed_id_for_query}":"#{type_de_champ_value}""
|
||||
)
|
||||
expect(response.body).not_to include(
|
||||
""champ_#{type_de_champ_to_remove.to_typed_id}": "#{type_de_champ_to_remove_value}""
|
||||
""champ_#{type_de_champ_to_remove.to_typed_id_for_query}":"#{type_de_champ_to_remove_value}""
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,6 +8,8 @@ RSpec.describe PrefillTypeDeChampsController, type: :controller do
|
|||
context 'when the procedure is found' do
|
||||
context 'when the procedure is publiee' do
|
||||
context 'when the procedure is opendata' do
|
||||
render_views
|
||||
|
||||
let(:procedure) { create(:procedure, :published, opendata: true) }
|
||||
|
||||
it { expect(show_request).to render_template(:show) }
|
||||
|
|
|
@ -196,6 +196,8 @@ describe Users::DossiersController, type: :controller do
|
|||
sign_in(user)
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}/)
|
||||
.to_return(status: api_etablissement_status, body: api_etablissement_body)
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}/)
|
||||
.to_return(body: File.read('spec/fixtures/files/api_entreprise/entreprises.json'), status: 200)
|
||||
allow_any_instance_of(APIEntrepriseToken).to receive(:roles)
|
||||
.and_return(["attestations_fiscales", "attestations_sociales", "bilans_entreprise_bdf"])
|
||||
allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(token_expired)
|
||||
|
@ -254,7 +256,7 @@ describe Users::DossiersController, type: :controller do
|
|||
|
||||
context 'When API-Entreprise is globally down' do
|
||||
let(:api_etablissement_status) { 502 }
|
||||
let(:api_current_status_response) { File.read('spec/fixtures/files/api_entreprise/current_status.json').tr('200', '502') }
|
||||
let(:api_current_status_response) { File.read('spec/fixtures/files/api_entreprise/current_status.json').gsub('200', '502') }
|
||||
|
||||
it "create an etablissement only with SIRET as degraded mode" do
|
||||
dossier.reload
|
||||
|
|
|
@ -97,7 +97,7 @@ FactoryBot.define do
|
|||
|
||||
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"]' }
|
||||
value { '["val1", "val2"]' }
|
||||
end
|
||||
|
||||
factory :champ_linked_drop_down_list, class: 'Champs::LinkedDropDownListChamp' do
|
||||
|
@ -122,7 +122,9 @@ FactoryBot.define do
|
|||
|
||||
factory :champ_communes, class: 'Champs::CommuneChamp' do
|
||||
type_de_champ { association :type_de_champ_communes, procedure: dossier.procedure }
|
||||
value { 'Paris' }
|
||||
value { 'Coye-la-Forêt (60580)' }
|
||||
value_json { { "departement" => "Oise", "code_departement" => "60" } }
|
||||
external_id { "60172" }
|
||||
end
|
||||
|
||||
factory :champ_epci, class: 'Champs::EpciChamp' do
|
||||
|
|
|
@ -206,6 +206,12 @@ FactoryBot.define do
|
|||
end
|
||||
end
|
||||
|
||||
trait :with_region do
|
||||
after(:build) do |procedure, _evaluator|
|
||||
build(:type_de_champ_regions, procedure: procedure)
|
||||
end
|
||||
end
|
||||
|
||||
trait :with_piece_justificative do
|
||||
after(:build) do |procedure, _evaluator|
|
||||
build(:type_de_champ_piece_justificative, procedure: procedure)
|
||||
|
|
|
@ -198,6 +198,16 @@ FactoryBot.define do
|
|||
parent = revision.revision_types_de_champ.find { |rtdc| rtdc.type_de_champ == type_de_champ_repetition }
|
||||
|
||||
build(:type_de_champ, procedure: evaluator.procedure, libelle: 'sub type de champ', parent: parent, position: 0)
|
||||
build(:type_de_champ, type_champ: TypeDeChamp.type_champs.fetch(:integer_number), procedure: evaluator.procedure, libelle: 'sub type de champ2', parent: parent, position: 1)
|
||||
end
|
||||
end
|
||||
|
||||
trait :with_region_types_de_champ do
|
||||
after(:build) do |type_de_champ_repetition, evaluator|
|
||||
revision = evaluator.procedure.active_revision
|
||||
parent = revision.revision_types_de_champ.find { |rtdc| rtdc.type_de_champ == type_de_champ_repetition }
|
||||
|
||||
build(:type_de_champ, type_champ: TypeDeChamp.type_champs.fetch(:regions), procedure: evaluator.procedure, libelle: 'region sub_champ', parent: parent, position: 10)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
16
spec/fixtures/cassettes/api_geo_all.yml
vendored
16
spec/fixtures/cassettes/api_geo_all.yml
vendored
File diff suppressed because one or more lines are too long
41
spec/fixtures/cassettes/api_geo_communes.yml
vendored
Normal file
41
spec/fixtures/cassettes/api_geo_communes.yml
vendored
Normal file
File diff suppressed because one or more lines are too long
12
spec/fixtures/cassettes/api_geo_departements.yml
vendored
12
spec/fixtures/cassettes/api_geo_departements.yml
vendored
File diff suppressed because one or more lines are too long
14
spec/fixtures/files/api_education/annuaire_education_empty.json
vendored
Normal file
14
spec/fixtures/files/api_education/annuaire_education_empty.json
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"nhits": 0,
|
||||
"parameters": {
|
||||
"dataset": "fr-en-annuaire-education",
|
||||
"rows": 1,
|
||||
"start": 0,
|
||||
"refine": {
|
||||
"identifiant_de_l_etablissement": "0341247"
|
||||
},
|
||||
"format": "json",
|
||||
"timezone": "UTC"
|
||||
},
|
||||
"records": []
|
||||
}
|
5
spec/fixtures/files/instructeurs-file.csv
vendored
Normal file
5
spec/fixtures/files/instructeurs-file.csv
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
Email
|
||||
kara@beta-gouv.fr
|
||||
philippe@mail.com
|
||||
lisa@gouv.fr
|
||||
eric
|
|
4
spec/fixtures/files/valid-instructeurs-file.csv
vendored
Normal file
4
spec/fixtures/files/valid-instructeurs-file.csv
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
Email
|
||||
kara@beta-gouv.fr
|
||||
philippe@mail.com
|
||||
lisa@gouv.fr
|
|
|
@ -8,6 +8,24 @@ RSpec.describe Types::DemarcheType, type: :graphql do
|
|||
let(:data) { subject['data'].deep_symbolize_keys }
|
||||
let(:errors) { subject['errors'].deep_symbolize_keys }
|
||||
|
||||
describe 'context should correctly preserve demarche authorization state' do
|
||||
let(:query) { DEMARCHE_QUERY }
|
||||
let(:admin) { create(:administrateur) }
|
||||
let(:procedure) { create(:procedure, administrateurs: [admin]) }
|
||||
|
||||
let(:other_admin_procedure) { create(:procedure) }
|
||||
let(:context) { { administrateur_id: admin.id } }
|
||||
let(:variables) { { number: procedure.id } }
|
||||
|
||||
it do
|
||||
result = API::V2::Schema.execute(query, variables: variables, context: context)
|
||||
graphql_context = result.context
|
||||
|
||||
expect(graphql_context.authorized_demarche?(procedure)).to be_truthy
|
||||
expect(graphql_context.authorized_demarche?(other_admin_procedure)).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
describe 'demarche with clone' do
|
||||
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :yes_no }]) }
|
||||
let(:procedure_clone) { procedure.clone(procedure.administrateurs.first, false) }
|
||||
|
@ -23,6 +41,13 @@ RSpec.describe Types::DemarcheType, type: :graphql do
|
|||
expect(procedure.draft_revision.types_de_champ_public.first.stable_id).to eq(procedure_clone.draft_revision.types_de_champ_public.first.stable_id)
|
||||
}
|
||||
end
|
||||
DEMARCHE_QUERY = <<-GRAPHQL
|
||||
query($number: Int!) {
|
||||
demarche(number: $number) {
|
||||
number
|
||||
}
|
||||
}
|
||||
GRAPHQL
|
||||
|
||||
DEMARCHE_WITH_CHAMP_DESCRIPTORS_QUERY = <<-GRAPHQL
|
||||
query($number: Int!) {
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
RSpec.describe StringToHtmlHelper, type: :helper do
|
||||
describe "#string_to_html" do
|
||||
let(:allow_a) { false }
|
||||
subject { string_to_html(description, allow_a:) }
|
||||
|
||||
context "with some simple texte" do
|
||||
let(:description) { "1er ligne \n 2ieme ligne" }
|
||||
|
||||
it { is_expected.to eq("<p>1er ligne \n<br> 2ieme ligne</p>") }
|
||||
end
|
||||
|
||||
context "with a link" do
|
||||
context "using an authorized scheme" do
|
||||
let(:description) { "Cliquez sur https://d-s.fr pour continuer." }
|
||||
|
||||
context 'with a tag authorized' do
|
||||
let(:allow_a) { true }
|
||||
it { is_expected.to eq("<p>Cliquez sur <a href=\"https://d-s.fr\" target=\"_blank\" rel=\"noopener\">https://d-s.fr</a> pour continuer.</p>") }
|
||||
end
|
||||
|
||||
context 'without a tag' do
|
||||
it { is_expected.to eq("<p>Cliquez sur https://d-s.fr pour continuer.</p>") }
|
||||
end
|
||||
end
|
||||
|
||||
context "using a non-authorized scheme" do
|
||||
let(:description) { "Cliquez sur file://etc/password pour continuer." }
|
||||
it { is_expected.to eq("<p>Cliquez sur file://etc/password pour continuer.</p>") }
|
||||
end
|
||||
|
||||
context "not actually an URL" do
|
||||
let(:description) { "Pour info: il ne devrait y avoir aucun lien." }
|
||||
it { is_expected.to eq("<p>Pour info: il ne devrait y avoir aucun lien.</p>") }
|
||||
end
|
||||
end
|
||||
|
||||
context "with empty decription" do
|
||||
let(:description) { nil }
|
||||
|
||||
it { is_expected.to eq nil }
|
||||
end
|
||||
|
||||
context "with a bad script" do
|
||||
let(:description) { '<script>bad</script>' }
|
||||
|
||||
it { is_expected.to eq('<p>bad</p>') }
|
||||
end
|
||||
end
|
||||
end
|
55
spec/jobs/champ_fetch_external_data_job_spec.rb
Normal file
55
spec/jobs/champ_fetch_external_data_job_spec.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ChampFetchExternalDataJob, type: :job do
|
||||
let(:champ) { Struct.new(:external_id, :data).new(champ_external_id, data) }
|
||||
let(:external_id) { "an ID" }
|
||||
let(:champ_external_id) { "an ID" }
|
||||
let(:data) { nil }
|
||||
let(:fetched_data) { nil }
|
||||
|
||||
subject(:perform_job) { described_class.perform_now(champ, external_id) }
|
||||
|
||||
before do
|
||||
allow(champ).to receive(:fetch_external_data).and_return(fetched_data)
|
||||
allow(champ).to receive(:update_with_external_data!)
|
||||
end
|
||||
|
||||
shared_examples "a champ non-updater" do
|
||||
it 'does not update the champ' do
|
||||
perform_job
|
||||
expect(champ).not_to have_received(:update_with_external_data!)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when external_id matches the champ external_id and the champ data is nil' do
|
||||
it 'fetches external data' do
|
||||
perform_job
|
||||
expect(champ).to have_received(:fetch_external_data)
|
||||
end
|
||||
|
||||
context 'when the fetched data is present' do
|
||||
let(:fetched_data) { "data" }
|
||||
|
||||
it 'updates the champ' do
|
||||
perform_job
|
||||
expect(champ).to have_received(:update_with_external_data!).with(data: fetched_data)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the fetched data is blank' do
|
||||
it_behaves_like "a champ non-updater"
|
||||
end
|
||||
end
|
||||
|
||||
context 'when external_id does not match the champ external_id' do
|
||||
let(:champ_external_id) { "something else" }
|
||||
it_behaves_like "a champ non-updater"
|
||||
end
|
||||
|
||||
context 'when the champ data is present' do
|
||||
let(:data) { "present" }
|
||||
it_behaves_like "a champ non-updater"
|
||||
end
|
||||
end
|
|
@ -38,4 +38,13 @@ describe APIEducation::AnnuaireEducationAdapter do
|
|||
expect { subject }.to raise_exception(APIEducation::AnnuaireEducationAdapter::InvalidSchemaError)
|
||||
end
|
||||
end
|
||||
|
||||
context "when responds with empty schema" do
|
||||
let(:body) { File.read('spec/fixtures/files/api_education/annuaire_education_empty.json') }
|
||||
let(:status) { 200 }
|
||||
|
||||
it '#to_params returns nil' do
|
||||
expect(subject).to eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,9 +21,9 @@ describe '20220705164551_remove_unused_champs' do
|
|||
|
||||
describe 'remove_unused_champs', vcr: { cassette_name: 'api_geo_all' } do
|
||||
it "with bad champs" do
|
||||
expect(Champ.where(dossier: dossier).count).to eq(38)
|
||||
expect(Champ.where(dossier: dossier).count).to eq(40)
|
||||
run_task
|
||||
expect(Champ.where(dossier: dossier).count).to eq(37)
|
||||
expect(Champ.where(dossier: dossier).count).to eq(39)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
describe '20230207144243_normalize_regions', vcr: { cassette_name: 'api_geo_regions' } do
|
||||
let(:champ) { create(:champ_regions) }
|
||||
let(:rake_task) { Rake::Task['after_party:normalize_regions'] }
|
||||
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
|
||||
|
||||
subject(:run_task) { rake_task.invoke }
|
||||
|
||||
before do
|
||||
allow(Rails).to receive(:cache).and_return(memory_store)
|
||||
Rails.cache.clear
|
||||
end
|
||||
|
||||
after { rake_task.reenable }
|
||||
|
||||
shared_examples "a non-changer" do |external_id, value|
|
||||
before { champ.update_columns(external_id:, value:) }
|
||||
|
||||
it { expect { run_task }.not_to change { champ.reload.external_id } }
|
||||
|
||||
it { expect { run_task }.not_to change { champ.reload.value } }
|
||||
end
|
||||
|
||||
shared_examples "an external_id nullifier" do |external_id, value|
|
||||
before { champ.update_columns(external_id:, value:) }
|
||||
|
||||
it { expect { run_task }.to change { champ.reload.external_id }.from(external_id).to(nil) }
|
||||
|
||||
it { expect { run_task }.not_to change { champ.reload.value } }
|
||||
end
|
||||
|
||||
shared_examples "a value nullifier" do |external_id, value|
|
||||
before { champ.update_columns(external_id:, value:) }
|
||||
|
||||
it { expect { run_task }.not_to change { champ.reload.external_id } }
|
||||
|
||||
it { expect { run_task }.to change { champ.reload.value }.from(value).to(nil) }
|
||||
end
|
||||
|
||||
shared_examples "an external_id and value nullifier" do |external_id, value|
|
||||
before { champ.update_columns(external_id:, value:) }
|
||||
|
||||
it { expect { run_task }.to change { champ.reload.external_id }.from(external_id).to(nil) }
|
||||
|
||||
it { expect { run_task }.to change { champ.reload.value }.from(value).to(nil) }
|
||||
end
|
||||
|
||||
shared_examples "an external_id updater" do |external_id, value, expected_external_id|
|
||||
before { champ.update_columns(external_id:, value:) }
|
||||
|
||||
it { expect { run_task }.to change { champ.reload.external_id }.from(external_id).to(expected_external_id) }
|
||||
|
||||
it { expect { run_task }.not_to change { champ.reload.value } }
|
||||
end
|
||||
|
||||
shared_examples "a result checker" do |external_id, value, expected_external_id, expected_value|
|
||||
before do
|
||||
champ.update_columns(external_id:, value:)
|
||||
run_task
|
||||
end
|
||||
|
||||
it { expect(champ.reload.external_id).to eq(expected_external_id) }
|
||||
|
||||
it { expect(champ.reload.value).to eq(expected_value) }
|
||||
end
|
||||
|
||||
shared_examples "a value updater" do |external_id, value, expected_value|
|
||||
before { champ.update_columns(external_id:, value:) }
|
||||
|
||||
it { expect { run_task }.not_to change { champ.reload.external_id } }
|
||||
|
||||
it { expect { run_task }.to change { champ.reload.value }.from(value).to(expected_value) }
|
||||
end
|
||||
|
||||
it_behaves_like "a non-changer", nil, nil
|
||||
it_behaves_like "an external_id nullifier", '', nil
|
||||
it_behaves_like "a value nullifier", nil, ''
|
||||
it_behaves_like "an external_id and value nullifier", '', ''
|
||||
it_behaves_like "an external_id updater", nil, 'Auvergne-Rhône-Alpes', '84'
|
||||
it_behaves_like "an external_id updater", '', 'Auvergne-Rhône-Alpes', '84'
|
||||
it_behaves_like "a value updater", '11', nil, 'Île-de-France'
|
||||
|
||||
# Integrity data check:
|
||||
it_behaves_like "a result checker", "84", "Auvergne-Rhône-Alpes", "84", "Auvergne-Rhône-Alpes"
|
||||
it_behaves_like "a result checker", nil, "Auvergne-Rhône-Alpes", "84", "Auvergne-Rhône-Alpes"
|
||||
it_behaves_like "a result checker", '', "Auvergne-Rhône-Alpes", "84", "Auvergne-Rhône-Alpes"
|
||||
it_behaves_like "a result checker", "27", "Bourgogne-Franche-Comté", "27", "Bourgogne-Franche-Comté"
|
||||
it_behaves_like "a result checker", nil, "Bourgogne-Franche-Comté", "27", "Bourgogne-Franche-Comté"
|
||||
it_behaves_like "a result checker", '', "Bourgogne-Franche-Comté", "27", "Bourgogne-Franche-Comté"
|
||||
it_behaves_like "a result checker", "53", "Bretagne", "53", "Bretagne"
|
||||
it_behaves_like "a result checker", nil, "Bretagne", "53", "Bretagne"
|
||||
it_behaves_like "a result checker", '', "Bretagne", "53", "Bretagne"
|
||||
it_behaves_like "a result checker", "24", "Centre-Val de Loire", "24", "Centre-Val de Loire"
|
||||
it_behaves_like "a result checker", nil, "Centre-Val de Loire", "24", "Centre-Val de Loire"
|
||||
it_behaves_like "a result checker", '', "Centre-Val de Loire", "24", "Centre-Val de Loire"
|
||||
it_behaves_like "a result checker", "94", "Corse", "94", "Corse"
|
||||
it_behaves_like "a result checker", nil, "Corse", "94", "Corse"
|
||||
it_behaves_like "a result checker", '', "Corse", "94", "Corse"
|
||||
it_behaves_like "a result checker", "44", "Grand Est", "44", "Grand Est"
|
||||
it_behaves_like "a result checker", nil, "Grand Est", "44", "Grand Est"
|
||||
it_behaves_like "a result checker", '', "Grand Est", "44", "Grand Est"
|
||||
it_behaves_like "a result checker", "01", "Guadeloupe", "01", "Guadeloupe"
|
||||
it_behaves_like "a result checker", nil, "Guadeloupe", "01", "Guadeloupe"
|
||||
it_behaves_like "a result checker", '', "Guadeloupe", "01", "Guadeloupe"
|
||||
it_behaves_like "a result checker", "03", "Guyane", "03", "Guyane"
|
||||
it_behaves_like "a result checker", nil, "Guyane", "03", "Guyane"
|
||||
it_behaves_like "a result checker", '', "Guyane", "03", "Guyane"
|
||||
it_behaves_like "a result checker", "32", "Hauts-de-France", "32", "Hauts-de-France"
|
||||
it_behaves_like "a result checker", nil, "Hauts-de-France", "32", "Hauts-de-France"
|
||||
it_behaves_like "a result checker", '', "Hauts-de-France", "32", "Hauts-de-France"
|
||||
it_behaves_like "a result checker", "04", "La Réunion", "04", "La Réunion"
|
||||
it_behaves_like "a result checker", nil, "La Réunion", "04", "La Réunion"
|
||||
it_behaves_like "a result checker", '', "La Réunion", "04", "La Réunion"
|
||||
it_behaves_like "a result checker", "02", "Martinique", "02", "Martinique"
|
||||
it_behaves_like "a result checker", nil, "Martinique", "02", "Martinique"
|
||||
it_behaves_like "a result checker", '', "Martinique", "02", "Martinique"
|
||||
it_behaves_like "a result checker", "06", "Mayotte", "06", "Mayotte"
|
||||
it_behaves_like "a result checker", nil, "Mayotte", "06", "Mayotte"
|
||||
it_behaves_like "a result checker", '', "Mayotte", "06", "Mayotte"
|
||||
it_behaves_like "a result checker", "28", "Normandie", "28", "Normandie"
|
||||
it_behaves_like "a result checker", nil, "Normandie", "28", "Normandie"
|
||||
it_behaves_like "a result checker", '', "Normandie", "28", "Normandie"
|
||||
it_behaves_like "a result checker", "75", "Nouvelle-Aquitaine", "75", "Nouvelle-Aquitaine"
|
||||
it_behaves_like "a result checker", nil, "Nouvelle-Aquitaine", "75", "Nouvelle-Aquitaine"
|
||||
it_behaves_like "a result checker", '', "Nouvelle-Aquitaine", "75", "Nouvelle-Aquitaine"
|
||||
it_behaves_like "a result checker", "76", "Occitanie", "76", "Occitanie"
|
||||
it_behaves_like "a result checker", nil, "Occitanie", "76", "Occitanie"
|
||||
it_behaves_like "a result checker", '', "Occitanie", "76", "Occitanie"
|
||||
it_behaves_like "a result checker", "52", "Pays de la Loire", "52", "Pays de la Loire"
|
||||
it_behaves_like "a result checker", nil, "Pays de la Loire", "52", "Pays de la Loire"
|
||||
it_behaves_like "a result checker", '', "Pays de la Loire", "52", "Pays de la Loire"
|
||||
it_behaves_like "a result checker", "93", "Provence-Alpes-Côte d'Azur", "93", "Provence-Alpes-Côte d’Azur"
|
||||
it_behaves_like "a result checker", nil, "Provence-Alpes-Côte d'Azur", "93", "Provence-Alpes-Côte d’Azur"
|
||||
it_behaves_like "a result checker", '', "Provence-Alpes-Côte d'Azur", "93", "Provence-Alpes-Côte d’Azur"
|
||||
it_behaves_like "a result checker", "93", "Provence-Alpes-Côte d’Azur", "93", "Provence-Alpes-Côte d’Azur"
|
||||
it_behaves_like "a result checker", "11", "Île-de-France", "11", "Île-de-France"
|
||||
it_behaves_like "a result checker", "11", nil, "11", "Île-de-France"
|
||||
it_behaves_like "a result checker", nil, "Île-de-France", "11", "Île-de-France"
|
||||
it_behaves_like "a result checker", '', "Île-de-France", "11", "Île-de-France"
|
||||
end
|
|
@ -1,5 +1,5 @@
|
|||
RSpec.describe GroupeInstructeurMailer, type: :mailer do
|
||||
describe '#remove_instructeurs' do
|
||||
describe '#notify_group_when_instructeurs_removed' do
|
||||
let(:groupe_instructeur) do
|
||||
gi = GroupeInstructeur.create(label: 'gi1', procedure: create(:procedure))
|
||||
gi.instructeurs << create(:instructeur, email: 'int1@g')
|
||||
|
@ -7,15 +7,78 @@ RSpec.describe GroupeInstructeurMailer, type: :mailer do
|
|||
gi.instructeurs << instructeurs_to_remove
|
||||
gi
|
||||
end
|
||||
let(:instructeur_1) { create(:instructeur, email: 'int3@g') }
|
||||
let(:instructeur_2) { create(:instructeur, email: 'int4@g') }
|
||||
let(:instructeur_3) { create(:instructeur, email: 'int3@g') }
|
||||
let(:instructeur_4) { create(:instructeur, email: 'int4@g') }
|
||||
|
||||
let(:instructeurs_to_remove) { [instructeur_1, instructeur_2] }
|
||||
let(:instructeurs_to_remove) { [instructeur_3, instructeur_4] }
|
||||
let(:current_instructeur_email) { 'toto@email.com' }
|
||||
|
||||
subject { described_class.remove_instructeurs(groupe_instructeur, instructeurs_to_remove, current_instructeur_email) }
|
||||
subject { described_class.notify_group_when_instructeurs_removed(groupe_instructeur, instructeurs_to_remove, current_instructeur_email) }
|
||||
|
||||
before { instructeurs_to_remove.each { groupe_instructeur.remove(_1) } }
|
||||
|
||||
it { expect(subject.body).to include('Les instructeurs int3@g, int4@g ont été retirés du groupe') }
|
||||
it { expect(subject.bcc).to match_array(['int1@g', 'int2@g', 'int3@g', 'int4@g']) }
|
||||
it { expect(subject.bcc).to match_array(['int1@g', 'int2@g']) }
|
||||
end
|
||||
|
||||
describe '#notify_removed_instructeur' do
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:groupe_instructeur) do
|
||||
gi = GroupeInstructeur.create(label: 'gi1', procedure: procedure)
|
||||
gi.instructeurs << create(:instructeur, email: 'int1@g')
|
||||
gi.instructeurs << create(:instructeur, email: 'int2@g')
|
||||
gi.instructeurs << instructeur_to_remove
|
||||
gi
|
||||
end
|
||||
let(:instructeur_to_remove) { create(:instructeur, email: 'int3@g') }
|
||||
|
||||
let(:current_instructeur_email) { 'toto@email.com' }
|
||||
|
||||
subject { described_class.notify_removed_instructeur(groupe_instructeur, instructeur_to_remove, current_instructeur_email) }
|
||||
|
||||
before { groupe_instructeur.remove(instructeur_to_remove) }
|
||||
|
||||
context 'when instructeur is fully removed form procedure' do
|
||||
it { expect(subject.body).to include('Vous avez été désaffecté(e) de la démarche') }
|
||||
it { expect(subject.to).to include('int3@g') }
|
||||
it { expect(subject.to).not_to include('int1@g', 'int2@g') }
|
||||
end
|
||||
|
||||
context 'when instructeur is removed from one group but still affected to procedure' do
|
||||
let!(:groupe_instructeur_2) do
|
||||
gi2 = GroupeInstructeur.create(label: 'gi2', procedure: procedure)
|
||||
gi2.instructeurs << instructeur_to_remove
|
||||
gi2
|
||||
end
|
||||
|
||||
it { expect(subject.body).to include('Vous avez été retiré(e) du groupe « gi1 » par « toto@email.com »') }
|
||||
it { expect(subject.to).to include('int3@g') }
|
||||
it { expect(subject.to).not_to include('int1@g', 'int2@g') }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#notify_added_instructeurs' do
|
||||
let(:procedure) { create(:procedure) }
|
||||
|
||||
let(:instructeurs_to_add) { [create(:instructeur, email: 'int3@g'), create(:instructeur, email: 'int4@g')] }
|
||||
|
||||
let(:current_instructeur_email) { 'toto@email.com' }
|
||||
|
||||
subject { described_class.notify_added_instructeurs(procedure.defaut_groupe_instructeur, instructeurs_to_add, current_instructeur_email) }
|
||||
|
||||
before { instructeurs_to_add.each { procedure.defaut_groupe_instructeur.add(_1) } }
|
||||
|
||||
context 'when there is only one group on procedure' do
|
||||
it { expect(subject.body).to include('Vous avez été affecté(e) à la démarche') }
|
||||
it { expect(subject.bcc).to match_array(['int3@g', 'int4@g']) }
|
||||
end
|
||||
|
||||
context 'when there are many groups on procedure' do
|
||||
let!(:groupe_instructeur_2) do
|
||||
GroupeInstructeur.create(label: 'gi2', procedure: procedure)
|
||||
end
|
||||
it { expect(subject.body).to include('Vous avez été ajouté(e) au groupe') }
|
||||
it { expect(subject.bcc).to match_array(['int3@g', 'int4@g']) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -101,4 +101,27 @@ RSpec.describe NotificationMailer, type: :mailer do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'subject length' do
|
||||
let(:procedure) { create(:simple_procedure, libelle: "My super long title " + ("xo " * 100)) }
|
||||
let(:dossier) { create(:dossier, :en_instruction, :with_individual, :with_service, user: user, procedure: procedure) }
|
||||
let(:email_template) { create(:closed_mail, subject:, body: 'Your dossier was accepted. Thanks.') }
|
||||
|
||||
before do
|
||||
dossier.procedure.closed_mail = email_template
|
||||
end
|
||||
|
||||
subject(:mail) { described_class.send_accepte_notification(dossier) }
|
||||
|
||||
context "subject is too long" do
|
||||
let(:subject) { 'Un long libellé --libellé démarche--' }
|
||||
it { expect(mail.subject.length).to be <= 100 }
|
||||
end
|
||||
|
||||
context "subject should fallback to default" do
|
||||
let(:subject) { "" }
|
||||
it { expect(mail.subject).to match(/^Votre dossier .+ a été accepté \(My super long title/) }
|
||||
it { expect(mail.subject.length).to be <= 100 }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,25 @@
|
|||
class GroupeInstructeurMailerPreview < ActionMailer::Preview
|
||||
def remove_instructeurs
|
||||
def notify_group_when_instructeurs_removed
|
||||
procedure = Procedure.new(id: 1, libelle: 'une superbe procedure')
|
||||
groupe = GroupeInstructeur.new(id: 1, label: 'Val-De-Marne', procedure:)
|
||||
current_instructeur_email = 'admin@dgfip.com'
|
||||
instructeurs = Instructeur.limit(2)
|
||||
GroupeInstructeurMailer.remove_instructeurs(groupe, instructeurs, current_instructeur_email)
|
||||
GroupeInstructeurMailer.notify_group_when_instructeurs_removed(groupe, instructeurs, current_instructeur_email)
|
||||
end
|
||||
|
||||
def notify_removed_instructeur
|
||||
procedure = Procedure.new(id: 1, libelle: 'une superbe procedure')
|
||||
groupe = GroupeInstructeur.new(id: 1, label: 'Val-De-Marne', procedure:)
|
||||
current_instructeur_email = 'admin@dgfip.com'
|
||||
instructeur = Instructeur.last
|
||||
GroupeInstructeurMailer.notify_removed_instructeur(groupe, instructeur, current_instructeur_email)
|
||||
end
|
||||
|
||||
def notify_added_instructeurs
|
||||
procedure = Procedure.new(id: 1, libelle: 'une superbe procedure')
|
||||
groupe = GroupeInstructeur.new(id: 1, label: 'Val-De-Marne', procedure:)
|
||||
current_instructeur_email = 'admin@dgfip.com'
|
||||
instructeurs = Instructeur.limit(2)
|
||||
GroupeInstructeurMailer.notify_added_instructeurs(groupe, instructeurs, current_instructeur_email)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -117,7 +117,7 @@ describe Champ do
|
|||
# when using the old form, and the ChampsService Class
|
||||
# TODO: to remove
|
||||
context 'when the value is already deserialized' do
|
||||
let(:value) { '["1", "2"]' }
|
||||
let(:value) { '["val1", "val2"]' }
|
||||
|
||||
it { expect(champ.value).to eq(value) }
|
||||
|
||||
|
@ -133,9 +133,9 @@ describe Champ do
|
|||
# GOTCHA
|
||||
context 'when the value is not already deserialized' do
|
||||
context 'when a choice is selected' do
|
||||
let(:value) { '["", "1", "2"]' }
|
||||
let(:value) { '["", "val1", "val2"]' }
|
||||
|
||||
it { expect(champ.value).to eq('["1", "2"]') }
|
||||
it { expect(champ.value).to eq('["val1", "val2"]') }
|
||||
end
|
||||
|
||||
context 'when all choices are removed' do
|
||||
|
@ -526,7 +526,7 @@ describe Champ do
|
|||
|
||||
expect(dossier.champs_public.size).to eq(2)
|
||||
expect(champ.rows.size).to eq(2)
|
||||
second_row = champ.rows.second
|
||||
second_row = champ.reload.rows.second
|
||||
expect(second_row.size).to eq(1)
|
||||
expect(second_row.first.dossier).to eq(dossier)
|
||||
|
||||
|
@ -602,4 +602,12 @@ describe Champ do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#update_with_external_data!' do
|
||||
let(:champ) { create(:champ_siret) }
|
||||
let(:data) { "data" }
|
||||
subject { champ.update_with_external_data!(data: data) }
|
||||
|
||||
it { expect { subject }.to change { champ.reload.data }.to(data) }
|
||||
end
|
||||
end
|
||||
|
|
42
spec/models/champs/annuaire_education_champ_spec.rb
Normal file
42
spec/models/champs/annuaire_education_champ_spec.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Champs::AnnuaireEducationChamp do
|
||||
describe '#update_with_external_data!' do
|
||||
let(:champ) { create(:champ_annuaire_education, data: "any data") }
|
||||
subject { champ.update_with_external_data!(data: data) }
|
||||
|
||||
shared_examples "a data updater (without updating the value)" do |data|
|
||||
it { expect { subject }.to change { champ.reload.data }.to(data) }
|
||||
it { expect { subject }.not_to change { champ.reload.value } }
|
||||
end
|
||||
|
||||
context 'when data is nil' do
|
||||
let(:data) { nil }
|
||||
it_behaves_like "a data updater (without updating the value)", nil
|
||||
end
|
||||
|
||||
context 'when data is empty' do
|
||||
let(:data) { '' }
|
||||
it_behaves_like "a data updater (without updating the value)", ''
|
||||
end
|
||||
|
||||
context 'when data is inconsistent' do
|
||||
let(:data) { { 'yo' => 'lo' } }
|
||||
it_behaves_like "a data updater (without updating the value)", { 'yo' => 'lo' }
|
||||
end
|
||||
|
||||
context 'when data is consistent' do
|
||||
let(:data) {
|
||||
{
|
||||
'nom_etablissement': "karrigel an ankou",
|
||||
'nom_commune' => 'kumun',
|
||||
'identifiant_de_l_etablissement' => '666667'
|
||||
}.with_indifferent_access
|
||||
}
|
||||
it { expect { subject }.to change { champ.reload.data }.to(data) }
|
||||
it { expect { subject }.to change { champ.reload.value }.to('karrigel an ankou, kumun (666667)') }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
describe Champs::CarteChamp do
|
||||
let(:champ) { Champs::CarteChamp.new(geo_areas: geo_areas, type_de_champ: create(:type_de_champ_carte)) }
|
||||
let(:value) { '' }
|
||||
let(:coordinates) { [[2.3859214782714844, 48.87442541960633], [2.3850631713867183, 48.87273183590832], [2.3809432983398438, 48.87081237174292], [2.3859214782714844, 48.87442541960633]] }
|
||||
let(:coordinates) { [[[2.3859214782714844, 48.87442541960633], [2.3850631713867183, 48.87273183590832], [2.3809432983398438, 48.87081237174292], [2.3859214782714844, 48.87442541960633]]] }
|
||||
let(:geo_json) do
|
||||
{
|
||||
"type" => 'Polygon',
|
||||
|
|
|
@ -6,9 +6,69 @@ describe Champs::DepartementChamp, type: :model do
|
|||
Rails.cache.clear
|
||||
end
|
||||
|
||||
let(:champ) { described_class.new }
|
||||
describe 'validations', vcr: { cassette_name: 'api_geo_departements' } do
|
||||
describe 'external link' do
|
||||
subject { build(:champ_departements, external_id: external_id) }
|
||||
|
||||
context 'when nil' do
|
||||
let(:external_id) { nil }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when blank' do
|
||||
let(:external_id) { '' }
|
||||
|
||||
it { is_expected.not_to be_valid }
|
||||
end
|
||||
|
||||
context 'when included in the departement codes' do
|
||||
let(:external_id) { "01" }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when not included in the departement codes' do
|
||||
let(:external_id) { "totoro" }
|
||||
|
||||
it { is_expected.not_to be_valid }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'value' do
|
||||
subject { create(:champ_departements) }
|
||||
|
||||
before { subject.update_columns(value: value) }
|
||||
|
||||
context 'when nil' do
|
||||
let(:value) { nil }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when blank' do
|
||||
let(:value) { '' }
|
||||
|
||||
it { is_expected.not_to be_valid }
|
||||
end
|
||||
|
||||
context 'when included in the departement names' do
|
||||
let(:value) { "Ain" }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when not included in the departement names' do
|
||||
let(:value) { "totoro" }
|
||||
|
||||
it { is_expected.not_to be_valid }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'value', vcr: { cassette_name: 'api_geo_departements' } do
|
||||
let(:champ) { described_class.new }
|
||||
|
||||
it 'with code having 2 chars' do
|
||||
champ.value = '01'
|
||||
expect(champ.external_id).to eq('01')
|
||||
|
|
37
spec/models/champs/dossier_link_champ_spec.rb
Normal file
37
spec/models/champs/dossier_link_champ_spec.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
describe Champs::DossierLinkChamp, type: :model do
|
||||
describe 'prefilling validations' do
|
||||
describe 'value' do
|
||||
subject { build(:champ_dossier_link, value: value).valid?(:prefill) }
|
||||
|
||||
context 'when nil' do
|
||||
let(:value) { nil }
|
||||
|
||||
it { expect(subject).to eq(true) }
|
||||
end
|
||||
|
||||
context 'when empty' do
|
||||
let(:value) { '' }
|
||||
|
||||
it { expect(subject).to eq(true) }
|
||||
end
|
||||
|
||||
context 'when an integer' do
|
||||
let(:value) { 42 }
|
||||
|
||||
it { expect(subject).to eq(true) }
|
||||
end
|
||||
|
||||
context 'when a string representing an integer' do
|
||||
let(:value) { "42" }
|
||||
|
||||
it { expect(subject).to eq(true) }
|
||||
end
|
||||
|
||||
context 'when it can be casted as integer' do
|
||||
let(:value) { 'totoro' }
|
||||
|
||||
it { expect(subject).to eq(false) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,9 +6,156 @@ describe Champs::EpciChamp, type: :model do
|
|||
Rails.cache.clear
|
||||
end
|
||||
|
||||
let(:champ) { described_class.new }
|
||||
describe 'validations' do
|
||||
describe 'code_departement', vcr: { cassette_name: 'api_geo_departements' } do
|
||||
subject { build(:champ_epci, code_departement: code_departement) }
|
||||
|
||||
context 'when nil' do
|
||||
let(:code_departement) { nil }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when empty' do
|
||||
let(:code_departement) { '' }
|
||||
|
||||
it { is_expected.not_to be_valid }
|
||||
end
|
||||
|
||||
context 'when included in the departement codes' do
|
||||
let(:code_departement) { "01" }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when not included in the departement codes' do
|
||||
let(:code_departement) { "totoro" }
|
||||
|
||||
it { is_expected.not_to be_valid }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'external_id' do
|
||||
let(:champ) { build(:champ_epci, code_departement: code_departement, external_id: nil) }
|
||||
|
||||
subject { champ }
|
||||
|
||||
before do
|
||||
VCR.insert_cassette('api_geo_departements')
|
||||
VCR.insert_cassette('api_geo_epcis')
|
||||
|
||||
champ.save!
|
||||
champ.update_columns(external_id: external_id)
|
||||
end
|
||||
|
||||
after do
|
||||
VCR.eject_cassette('api_geo_departements')
|
||||
VCR.eject_cassette('api_geo_epcis')
|
||||
end
|
||||
|
||||
context 'when code_departement is nil' do
|
||||
let(:code_departement) { nil }
|
||||
let(:external_id) { nil }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when code_departement is not nil and valid' do
|
||||
let(:code_departement) { "01" }
|
||||
|
||||
context 'when external_id is nil' do
|
||||
let(:external_id) { nil }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when external_id is empty' do
|
||||
let(:external_id) { '' }
|
||||
|
||||
it { is_expected.not_to be_valid }
|
||||
end
|
||||
|
||||
context 'when external_id is included in the epci codes of the departement' do
|
||||
let(:external_id) { '200042935' }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when external_id is not included in the epci codes of the departement' do
|
||||
let(:external_id) { 'totoro' }
|
||||
|
||||
it { is_expected.not_to be_valid }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'value' do
|
||||
let(:champ) { build(:champ_epci, code_departement: code_departement, external_id: nil, value: nil) }
|
||||
|
||||
subject { champ }
|
||||
|
||||
before do
|
||||
VCR.insert_cassette('api_geo_departements')
|
||||
VCR.insert_cassette('api_geo_epcis')
|
||||
|
||||
champ.save!
|
||||
champ.update_columns(external_id: external_id, value: value)
|
||||
end
|
||||
|
||||
after do
|
||||
VCR.eject_cassette('api_geo_departements')
|
||||
VCR.eject_cassette('api_geo_epcis')
|
||||
end
|
||||
|
||||
context 'when code_departement is nil' do
|
||||
let(:code_departement) { nil }
|
||||
let(:external_id) { nil }
|
||||
let(:value) { nil }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when external_id is nil' do
|
||||
let(:code_departement) { '01' }
|
||||
let(:external_id) { nil }
|
||||
let(:value) { nil }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when code_departement and external_id are not nil and valid' do
|
||||
let(:code_departement) { '01' }
|
||||
let(:external_id) { '200042935' }
|
||||
|
||||
context 'when value is nil' do
|
||||
let(:value) { nil }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when value is empty' do
|
||||
let(:value) { '' }
|
||||
|
||||
it { is_expected.not_to be_valid }
|
||||
end
|
||||
|
||||
context 'when value is in departement epci names' do
|
||||
let(:value) { 'CA Haut - Bugey Agglomération' }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when value is not in departement epci names' do
|
||||
let(:value) { 'totoro' }
|
||||
|
||||
it { is_expected.not_to be_valid }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'value', vcr: { cassette_name: 'api_geo_epcis' } do
|
||||
let(:champ) { described_class.new }
|
||||
it 'with departement and code' do
|
||||
champ.code_departement = '01'
|
||||
champ.value = '200042935'
|
||||
|
|
38
spec/models/champs/multiple_drop_down_list_champ_spec.rb
Normal file
38
spec/models/champs/multiple_drop_down_list_champ_spec.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
describe Champs::MultipleDropDownListChamp do
|
||||
describe 'validations' do
|
||||
describe 'inclusion' do
|
||||
let(:type_de_champ) { build(:type_de_champ_multiple_drop_down_list, drop_down_list_value: "val1\r\nval2\r\nval3") }
|
||||
subject { build(:champ_multiple_drop_down_list, type_de_champ:, value:) }
|
||||
|
||||
context 'when the value is nil' do
|
||||
let(:value) { nil }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when the value is an empty string' do
|
||||
let(:value) { '' }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when the value is an empty array' do
|
||||
let(:value) { [] }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when the value is included in the option list' do
|
||||
let(:value) { ["val3", "val1"] }
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'when the value is not included in the option list' do
|
||||
let(:value) { ["totoro", "val1"] }
|
||||
|
||||
it { is_expected.not_to be_valid }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,7 +6,10 @@ RSpec.describe DossierPrefillableConcern do
|
|||
let(:dossier) { create(:dossier, :brouillon, procedure: procedure) }
|
||||
let(:types_de_champ_public) { [] }
|
||||
|
||||
subject(:fill) { dossier.prefill!(values); dossier.reload }
|
||||
subject(:fill) do
|
||||
dossier.prefill!(values)
|
||||
dossier.reload
|
||||
end
|
||||
|
||||
shared_examples 'a dossier marked as prefilled' do
|
||||
it 'marks the dossier as prefilled' do
|
||||
|
|
69
spec/models/concern/dossier_sections_concern_spec.rb
Normal file
69
spec/models/concern/dossier_sections_concern_spec.rb
Normal file
|
@ -0,0 +1,69 @@
|
|||
describe DossierSectionsConcern do
|
||||
describe '#auto_numbering_section_headers_for?' do
|
||||
let(:public_libelle) { "Infos" }
|
||||
let(:private_libelle) { "Infos Private" }
|
||||
let(:types_de_champ_public) { [{ type: :header_section, libelle: public_libelle }, { type: :header_section, libelle: "Details" }] }
|
||||
let(:types_de_champ_private) { [{ type: :header_section, libelle: private_libelle }, { type: :header_section, libelle: "Details Private" }] }
|
||||
|
||||
let(:procedure) { create(:procedure, :for_individual, types_de_champ_public:, types_de_champ_private:) }
|
||||
let(:dossier) { create(:dossier, procedure: procedure) }
|
||||
|
||||
context "with no section having number" do
|
||||
it { expect(dossier.auto_numbering_section_headers_for?(dossier.champs_public[1])).to eq(true) }
|
||||
it { expect(dossier.auto_numbering_section_headers_for?(dossier.champs_private[1])).to eq(true) }
|
||||
end
|
||||
|
||||
context "with public section having number" do
|
||||
let(:public_libelle) { "1 - infos" }
|
||||
it { expect(dossier.auto_numbering_section_headers_for?(dossier.champs_public[1])).to eq(false) }
|
||||
it { expect(dossier.auto_numbering_section_headers_for?(dossier.champs_private[1])).to eq(true) }
|
||||
end
|
||||
|
||||
context "with private section having number" do
|
||||
let(:private_libelle) { "1 - infos private" }
|
||||
it { expect(dossier.auto_numbering_section_headers_for?(dossier.champs_public[1])).to eq(true) }
|
||||
it { expect(dossier.auto_numbering_section_headers_for?(dossier.champs_private[1])).to eq(false) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#index_for_section_header' do
|
||||
include Logic
|
||||
let(:number_stable_id) { 99 }
|
||||
let(:types_de_champ) {
|
||||
[
|
||||
{ type: :header_section, libelle: "Infos" }, { type: :integer_number, stable_id: number_stable_id },
|
||||
{ type: :header_section, libelle: "Details", condition: ds_eq(champ_value(99), constant(5)) }, { type: :header_section, libelle: "Conclusion" }
|
||||
]
|
||||
}
|
||||
|
||||
let(:procedure) { create(:procedure, :for_individual, types_de_champ_public: types_de_champ) }
|
||||
let(:dossier) { create(:dossier, procedure: procedure) }
|
||||
|
||||
let(:headers) { dossier.champs_public.filter(&:header_section?) }
|
||||
|
||||
let(:number_value) { nil }
|
||||
|
||||
before do
|
||||
dossier.champs_public.find { _1.stable_id == number_stable_id }.update(value: number_value)
|
||||
dossier.reload
|
||||
end
|
||||
|
||||
context "when there are invisible sections" do
|
||||
it "index accordingly header sections" do
|
||||
expect(dossier.index_for_section_header(headers[0])).to eq(1)
|
||||
expect(headers[1]).not_to be_visible
|
||||
expect(dossier.index_for_section_header(headers[2])).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
context "when all headers are visible" do
|
||||
let(:number_value) { 5 }
|
||||
it "index accordingly header sections" do
|
||||
expect(dossier.index_for_section_header(headers[0])).to eq(1)
|
||||
expect(headers[1]).to be_visible
|
||||
expect(dossier.index_for_section_header(headers[1])).to eq(2)
|
||||
expect(dossier.index_for_section_header(headers[2])).to eq(3)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,15 +7,17 @@ describe ProcedureStatsConcern do
|
|||
before do
|
||||
create_list(:dossier, 2, :brouillon, procedure: procedure)
|
||||
create(:dossier, :en_instruction, procedure: procedure)
|
||||
create(:dossier, procedure: procedure, for_procedure_preview: true)
|
||||
create(:dossier, :accepte, procedure: procedure, hidden_by_administration_at: Time.zone.now)
|
||||
end
|
||||
|
||||
it "returns the funnel stats" do
|
||||
expect(stats_dossiers_funnel).to match(
|
||||
[
|
||||
['Démarrés', procedure.dossiers.count],
|
||||
['Déposés', procedure.dossiers.state_not_brouillon.count],
|
||||
['Instruction débutée', procedure.dossiers.state_instruction_commencee.count],
|
||||
['Traités', procedure.dossiers.state_termine.count]
|
||||
['Démarrés', procedure.dossiers.visible_by_user_or_administration.count],
|
||||
['Déposés', procedure.dossiers.visible_by_administration.count],
|
||||
['Instruction débutée', procedure.dossiers.visible_by_administration.state_instruction_commencee.count],
|
||||
['Traités', procedure.dossiers.visible_by_administration.state_termine.count]
|
||||
]
|
||||
)
|
||||
end
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
RSpec.describe RNAChampAssociationFetchableConcern do
|
||||
describe '.fetch_association!' do
|
||||
let!(:champ) { create(:champ_rna, data: "not nil data", value: 'W173847273') }
|
||||
|
||||
before do
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/associations\//)
|
||||
.to_return(body: body, status: status)
|
||||
allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(false)
|
||||
end
|
||||
|
||||
subject(:fetch_association!) { champ.fetch_association!(rna) }
|
||||
|
||||
shared_examples "an association fetcher" do |expected_result, expected_error, expected_value, expected_data|
|
||||
it { expect { fetch_association! }.to change { champ.reload.value }.to(expected_value) }
|
||||
|
||||
it { expect { fetch_association! }.to change { champ.reload.data }.to(expected_data) }
|
||||
|
||||
it { expect(fetch_association!).to eq(expected_result) }
|
||||
|
||||
it 'populates the association_fetch_error_key when an error occurs' do
|
||||
fetch_association!
|
||||
expect(champ.association_fetch_error_key).to eq(expected_error)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the RNA is empty' do
|
||||
let(:rna) { '' }
|
||||
let(:status) { 422 }
|
||||
let(:body) { '' }
|
||||
|
||||
it_behaves_like "an association fetcher", false, :empty, '', nil
|
||||
end
|
||||
|
||||
context 'when the RNA is invalid' do
|
||||
let(:rna) { '1234' }
|
||||
let(:status) { 422 }
|
||||
let(:body) { '' }
|
||||
|
||||
it_behaves_like "an association fetcher", false, :invalid, '1234', nil
|
||||
end
|
||||
|
||||
context 'when the RNA is unknow' do
|
||||
let(:rna) { 'W111111111' }
|
||||
let(:status) { 404 }
|
||||
let(:body) { '' }
|
||||
|
||||
it_behaves_like "an association fetcher", false, :not_found, 'W111111111', nil
|
||||
end
|
||||
|
||||
context 'when the API is unavailable due to network error' do
|
||||
let(:rna) { 'W595001988' }
|
||||
let(:status) { 503 }
|
||||
let(:body) { File.read('spec/fixtures/files/api_entreprise/associations.json') }
|
||||
|
||||
before { expect(APIEntrepriseService).to receive(:api_up?).and_return(false) }
|
||||
|
||||
it_behaves_like "an association fetcher", false, :network_error, 'W595001988', nil
|
||||
end
|
||||
|
||||
context 'when the RNA informations are retrieved successfully' do
|
||||
let(:rna) { 'W595001988' }
|
||||
let(:status) { 200 }
|
||||
let(:body) { File.read('spec/fixtures/files/api_entreprise/associations.json') }
|
||||
|
||||
it_behaves_like "an association fetcher", true, nil, 'W595001988', {
|
||||
"association_id" => "W595001988",
|
||||
"association_titre" => "UN SUR QUATRE",
|
||||
"association_objet" => "valoriser, transmettre et partager auprès des publics les plus larges possibles, les bienfaits de l'immigration, la richesse de la diversité et la curiosité de l'autre autrement",
|
||||
"association_siret" => nil,
|
||||
"association_date_creation" => "2014-01-23",
|
||||
"association_date_declaration" => "2014-01-24",
|
||||
"association_date_publication" => "2014-02-08",
|
||||
"association_date_dissolution" => "0001-01-01",
|
||||
"association_adresse_siege" => {
|
||||
"complement" => "",
|
||||
"numero_voie" => "61",
|
||||
"type_voie" => "RUE",
|
||||
"libelle_voie" => "des Noyers",
|
||||
"distribution" => "_",
|
||||
"code_insee" => "93063",
|
||||
"code_postal" => "93230",
|
||||
"commune" => "Romainville"
|
||||
},
|
||||
"association_code_civilite_dirigeant" => "PM",
|
||||
"association_civilite_dirigeant" => "Monsieur le Président",
|
||||
"association_code_etat" => "A",
|
||||
"association_etat" => "Active",
|
||||
"association_code_groupement" => "S",
|
||||
"association_groupement" => "simple",
|
||||
"association_mise_a_jour" => 1392295833,
|
||||
"association_rna" => "W595001988"
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,115 @@
|
|||
RSpec.describe SiretChampEtablissementFetchableConcern do
|
||||
describe '.fetch_etablissement!' do
|
||||
let(:api_etablissement_status) { 200 }
|
||||
let(:api_etablissement_body) { File.read('spec/fixtures/files/api_entreprise/etablissements.json') }
|
||||
let(:token_expired) { false }
|
||||
let!(:champ) { create(:champ_siret) }
|
||||
|
||||
before do
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}/)
|
||||
.to_return(status: api_etablissement_status, body: api_etablissement_body)
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siret[0..8]}/)
|
||||
.to_return(body: File.read('spec/fixtures/files/api_entreprise/entreprises.json'), status: 200)
|
||||
allow_any_instance_of(APIEntrepriseToken).to receive(:roles)
|
||||
.and_return(["attestations_fiscales", "attestations_sociales", "bilans_entreprise_bdf"])
|
||||
allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(token_expired)
|
||||
end
|
||||
|
||||
subject(:fetch_etablissement!) { champ.fetch_etablissement!(siret, build_stubbed(:user)) }
|
||||
|
||||
shared_examples 'an error occured' do |error|
|
||||
it { expect { fetch_etablissement! }.to change { champ.reload.etablissement }.to(nil) }
|
||||
|
||||
it { expect { fetch_etablissement! }.to change { Etablissement.count }.by(-1) }
|
||||
|
||||
it { expect(fetch_etablissement!).to eq(false) }
|
||||
|
||||
it 'populates the etablissement_fetch_error_key' do
|
||||
fetch_etablissement!
|
||||
expect(champ.etablissement_fetch_error_key).to eq(error)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the SIRET is empty' do
|
||||
let(:siret) { '' }
|
||||
|
||||
it_behaves_like 'an error occured', :empty
|
||||
end
|
||||
|
||||
context "when the SIRET is invalid because of it's length" do
|
||||
let(:siret) { '1234' }
|
||||
|
||||
it_behaves_like 'an error occured', :invalid_length
|
||||
end
|
||||
|
||||
context "when the SIRET is invalid because of it's checksum" do
|
||||
let(:siret) { '82812345600023' }
|
||||
|
||||
it_behaves_like 'an error occured', :invalid_checksum
|
||||
end
|
||||
|
||||
context 'when the API is unavailable due to network error' do
|
||||
let(:siret) { '82161143100015' }
|
||||
let(:api_etablissement_status) { 503 }
|
||||
|
||||
before { expect(APIEntrepriseService).to receive(:api_up?).and_return(true) }
|
||||
|
||||
it_behaves_like 'an error occured', :network_error
|
||||
|
||||
it 'sends the error to Sentry' do
|
||||
expect(Sentry).to receive(:capture_exception)
|
||||
fetch_etablissement!
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the API is unavailable due to an api maintenance or pb' do
|
||||
let(:siret) { '82161143100015' }
|
||||
let(:api_etablissement_status) { 502 }
|
||||
|
||||
before { expect(APIEntrepriseService).to receive(:api_up?).and_return(false) }
|
||||
|
||||
it { expect { fetch_etablissement! }.to change { champ.reload.value }.to(siret) }
|
||||
|
||||
it { expect { fetch_etablissement! }.to change { champ.reload.etablissement } }
|
||||
|
||||
it { expect { fetch_etablissement! }.to change { champ.reload.etablissement.as_degraded_mode? }.to(true) }
|
||||
|
||||
it { expect { fetch_etablissement! }.to change { Etablissement.count }.by(1) }
|
||||
|
||||
it { expect(fetch_etablissement!).to eq(false) }
|
||||
|
||||
it 'populates the etablissement_fetch_error_key' do
|
||||
fetch_etablissement!
|
||||
expect(champ.etablissement_fetch_error_key).to eq(:api_entreprise_down)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the SIRET is valid but unknown' do
|
||||
let(:siret) { '00000000000000' }
|
||||
let(:api_etablissement_status) { 404 }
|
||||
|
||||
it_behaves_like 'an error occured', :not_found
|
||||
end
|
||||
|
||||
context 'when the SIRET informations are retrieved successfully' do
|
||||
let(:siret) { '41816609600051' }
|
||||
let(:api_etablissement_status) { 200 }
|
||||
let(:api_etablissement_body) { File.read('spec/fixtures/files/api_entreprise/etablissements.json') }
|
||||
|
||||
it { expect { fetch_etablissement! }.to change { champ.reload.value }.to(siret) }
|
||||
|
||||
it { expect { fetch_etablissement! }.to change { champ.reload.etablissement.siret }.to(siret) }
|
||||
|
||||
it { expect { fetch_etablissement! }.to change { champ.reload.etablissement.naf }.to("6202A") }
|
||||
|
||||
it { expect { fetch_etablissement! }.to change { Etablissement.count }.by(1) }
|
||||
|
||||
it { expect(fetch_etablissement!).to eq(true) }
|
||||
|
||||
it "fetches the entreprise raison sociale" do
|
||||
fetch_etablissement!
|
||||
expect(champ.reload.etablissement.entreprise_raison_sociale).to eq("OCTO-TECHNOLOGY")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1516,8 +1516,8 @@ describe Dossier do
|
|||
{
|
||||
type: 'Feature',
|
||||
geometry: {
|
||||
'coordinates' => [[[2.428439855575562, 46.538476837725796], [2.4284291267395024, 46.53842148758162], [2.4282521009445195, 46.53841410755813], [2.42824137210846, 46.53847314771794], [2.428284287452698, 46.53847314771794], [2.428364753723145, 46.538487907747864], [2.4284291267395024, 46.538491597754714], [2.428439855575562, 46.538476837725796]]],
|
||||
'type' => 'Polygon'
|
||||
coordinates: [[[2.428439855575562, 46.538476837725796], [2.4284291267395024, 46.53842148758162], [2.4282521009445195, 46.53841410755813], [2.42824137210846, 46.53847314771794], [2.428284287452698, 46.53847314771794], [2.428364753723145, 46.538487907747864], [2.4284291267395024, 46.538491597754714], [2.428439855575562, 46.538476837725796]]],
|
||||
type: 'Polygon'
|
||||
},
|
||||
properties: {
|
||||
area: 103.6,
|
||||
|
@ -1861,7 +1861,7 @@ describe Dossier do
|
|||
let(:champ_repetition) { create(:champ_repetition, type_de_champ: type_de_champ_repetition, dossier: dossier) }
|
||||
before { dossier.champs_public << champ_repetition }
|
||||
|
||||
it { expect(Champs::RepetitionChamp.where(dossier: new_dossier).first.champs.count).to eq(2) }
|
||||
it { expect(Champs::RepetitionChamp.where(dossier: new_dossier).first.champs.count).to eq(4) }
|
||||
it { expect(Champs::RepetitionChamp.where(dossier: new_dossier).first.champs.ids).not_to eq(champ_repetition.champs.ids) }
|
||||
end
|
||||
|
||||
|
@ -2080,6 +2080,15 @@ describe Dossier do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'update procedure dossiers count' do
|
||||
let(:dossier) { create(:dossier, :brouillon, :with_individual) }
|
||||
|
||||
it 'update procedure dossiers count when passing to construction' do
|
||||
expect(dossier.procedure).to receive(:compute_dossiers_count)
|
||||
dossier.passer_en_construction!
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def count_for_month(processed_by_month, month)
|
||||
|
|
|
@ -23,7 +23,7 @@ RSpec.describe GeoArea, type: :model do
|
|||
it { expect(geo_area.location).to eq("46°32'19\"N 2°25'42\"E") }
|
||||
end
|
||||
|
||||
describe '#rgeo_geometry' do
|
||||
describe '#geometry' do
|
||||
let(:geo_area) { build(:geo_area, :polygon, champ: nil) }
|
||||
let(:polygon) do
|
||||
{
|
||||
|
@ -47,9 +47,9 @@ RSpec.describe GeoArea, type: :model do
|
|||
|
||||
context 'polygon_with_extra_coordinate' do
|
||||
let(:geo_area) { build(:geo_area, :polygon_with_extra_coordinate, champ: nil) }
|
||||
before { geo_area.valid? }
|
||||
|
||||
it { expect(geo_area.geometry).not_to eq(polygon) }
|
||||
it { expect(geo_area.safe_geometry).to eq(polygon) }
|
||||
it { expect(geo_area.geometry).to eq(polygon) }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ RSpec.describe PrefillDescription, type: :model do
|
|||
|
||||
it { expect(types_de_champ.count).to eq(1) }
|
||||
|
||||
it { expect(types_de_champ.first).to eql(TypesDeChamp::PrefillTypeDeChamp.build(type_de_champ)) }
|
||||
it { expect(types_de_champ.first).to eql(TypesDeChamp::PrefillTypeDeChamp.build(type_de_champ, procedure.active_revision)) }
|
||||
|
||||
shared_examples "filters out non fillable types de champ" do |type_de_champ_name|
|
||||
context "when the procedure has a #{type_de_champ_name} champ" do
|
||||
|
@ -86,36 +86,80 @@ RSpec.describe PrefillDescription, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#prefill_link' do
|
||||
describe '#prefill_link', vcr: { cassette_name: 'api_geo_regions' } do
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:type_de_champ) { create(:type_de_champ_text, procedure: procedure) }
|
||||
let(:type_de_champ_text) { build(:type_de_champ_text, procedure: procedure) }
|
||||
let(:type_de_champ_epci) { build(:type_de_champ_epci, procedure: procedure) }
|
||||
let(:type_de_champ_repetition) { create(:type_de_champ_repetition, :with_types_de_champ, :with_region_types_de_champ, procedure: procedure) }
|
||||
let(:prefillable_subchamps) { TypesDeChamp::PrefillRepetitionTypeDeChamp.new(type_de_champ_repetition, procedure.active_revision).send(:prefillable_subchamps) }
|
||||
let(:region_repetition) { prefillable_subchamps.third }
|
||||
let(:prefill_description) { described_class.new(procedure) }
|
||||
|
||||
before { prefill_description.update(selected_type_de_champ_ids: [type_de_champ.id]) }
|
||||
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
|
||||
|
||||
before do
|
||||
allow(Rails).to receive(:cache).and_return(memory_store)
|
||||
Rails.cache.clear
|
||||
|
||||
VCR.insert_cassette('api_geo_departements')
|
||||
VCR.insert_cassette('api_geo_epcis')
|
||||
|
||||
prefill_description.update(selected_type_de_champ_ids: [type_de_champ_text.id, type_de_champ_epci.id, type_de_champ_repetition.id])
|
||||
end
|
||||
|
||||
after do
|
||||
VCR.eject_cassette('api_geo_departements')
|
||||
VCR.eject_cassette('api_geo_epcis')
|
||||
end
|
||||
|
||||
it "builds the URL to create a new prefilled dossier" do
|
||||
expect(prefill_description.prefill_link).to eq(
|
||||
commencer_url(
|
||||
path: procedure.path,
|
||||
"champ_#{type_de_champ.to_typed_id}" => I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")
|
||||
CGI.unescape(
|
||||
commencer_url(
|
||||
path: procedure.path,
|
||||
"champ_#{type_de_champ_text.to_typed_id_for_query}" => TypesDeChamp::PrefillTypeDeChamp.build(type_de_champ_text, procedure.active_revision).example_value,
|
||||
"champ_#{type_de_champ_epci.to_typed_id_for_query}" => TypesDeChamp::PrefillTypeDeChamp.build(type_de_champ_epci, procedure.active_revision).example_value,
|
||||
"champ_#{type_de_champ_repetition.to_typed_id_for_query}" => TypesDeChamp::PrefillTypeDeChamp.build(type_de_champ_repetition, procedure.active_revision).example_value
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#prefill_query' do
|
||||
describe '#prefill_query', vcr: { cassette_name: 'api_geo_regions' } do
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:type_de_champ) { create(:type_de_champ_text, procedure: procedure) }
|
||||
let(:type_de_champ_text) { create(:type_de_champ_text, procedure: procedure) }
|
||||
let(:type_de_champ_epci) { TypesDeChamp::PrefillTypeDeChamp.build(create(:type_de_champ_epci, procedure: procedure), procedure.active_revision) }
|
||||
let(:type_de_champ_repetition) { build(:type_de_champ_repetition, :with_types_de_champ, :with_region_types_de_champ, procedure: procedure) }
|
||||
let(:prefillable_subchamps) { TypesDeChamp::PrefillRepetitionTypeDeChamp.new(type_de_champ_repetition, 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(:prefill_description) { described_class.new(procedure) }
|
||||
let(:expected_query) do
|
||||
<<~TEXT
|
||||
curl --request POST '#{api_public_v1_dossiers_url(procedure)}' \\
|
||||
--header 'Content-Type: application/json' \\
|
||||
--data '{"champ_#{type_de_champ.to_typed_id}": "#{I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")}"}'
|
||||
--data '{"champ_#{type_de_champ_text.to_typed_id_for_query}":"Texte court","champ_#{type_de_champ_epci.to_typed_id_for_query}":["01","200042935"],"champ_#{type_de_champ_repetition.to_typed_id_for_query}":[{"champ_#{text_repetition.to_typed_id_for_query}":"Texte court","champ_#{integer_repetition.to_typed_id_for_query}":"42","champ_#{region_repetition.to_typed_id_for_query}":"53"},{"champ_#{text_repetition.to_typed_id_for_query}":"Texte court","champ_#{integer_repetition.to_typed_id_for_query}":"42","champ_#{region_repetition.to_typed_id_for_query}":"53"}]}'
|
||||
TEXT
|
||||
end
|
||||
|
||||
before { prefill_description.update(selected_type_de_champ_ids: [type_de_champ.id]) }
|
||||
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
|
||||
|
||||
before do
|
||||
allow(Rails).to receive(:cache).and_return(memory_store)
|
||||
Rails.cache.clear
|
||||
|
||||
VCR.insert_cassette('api_geo_departements')
|
||||
VCR.insert_cassette('api_geo_epcis')
|
||||
|
||||
prefill_description.update(selected_type_de_champ_ids: [type_de_champ_text.id, type_de_champ_epci.id, type_de_champ_repetition.id])
|
||||
end
|
||||
|
||||
after do
|
||||
VCR.eject_cassette('api_geo_departements')
|
||||
VCR.eject_cassette('api_geo_epcis')
|
||||
end
|
||||
|
||||
it "builds the query to create a new prefilled dossier" do
|
||||
expect(prefill_description.prefill_query).to eq(expected_query)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
RSpec.describe PrefillParams do
|
||||
describe "#to_a", vcr: { cassette_name: 'api_geo_regions' } do
|
||||
describe "#to_a", vcr: { cassette_name: 'api_geo_all' } do
|
||||
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
|
||||
|
||||
let(:procedure) { create(:procedure, :published, types_de_champ_public:, types_de_champ_private:) }
|
||||
|
@ -12,6 +12,18 @@ RSpec.describe PrefillParams do
|
|||
before do
|
||||
allow(Rails).to receive(:cache).and_return(memory_store)
|
||||
Rails.cache.clear
|
||||
|
||||
VCR.insert_cassette('api_geo_regions')
|
||||
VCR.insert_cassette('api_geo_departements')
|
||||
VCR.insert_cassette('api_geo_communes')
|
||||
VCR.insert_cassette('api_geo_epcis')
|
||||
end
|
||||
|
||||
after do
|
||||
VCR.eject_cassette('api_geo_regions')
|
||||
VCR.eject_cassette('api_geo_departements')
|
||||
VCR.eject_cassette('api_geo_communes')
|
||||
VCR.eject_cassette('api_geo_epcis')
|
||||
end
|
||||
|
||||
context "when the stable ids match the TypeDeChamp of the corresponding procedure" do
|
||||
|
@ -26,8 +38,8 @@ RSpec.describe PrefillParams do
|
|||
|
||||
let(:params) {
|
||||
{
|
||||
"champ_#{type_de_champ_1.to_typed_id}" => value_1,
|
||||
"champ_#{type_de_champ_2.to_typed_id}" => value_2
|
||||
"champ_#{type_de_champ_1.to_typed_id_for_query}" => value_1,
|
||||
"champ_#{type_de_champ_2.to_typed_id_for_query}" => value_2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +55,7 @@ RSpec.describe PrefillParams do
|
|||
let(:type_de_champ) { procedure.published_revision.types_de_champ_public.first }
|
||||
let(:types_de_champ_public) { [{ type: :text }] }
|
||||
|
||||
let(:params) { { type_de_champ.to_typed_id => "value" } }
|
||||
let(:params) { { type_de_champ.to_typed_id_for_query => "value" } }
|
||||
|
||||
it "filters out the champ" do
|
||||
expect(prefill_params_array).to match([])
|
||||
|
@ -61,7 +73,7 @@ RSpec.describe PrefillParams do
|
|||
context 'when there is no Champ that matches the TypeDeChamp with the given stable id' do
|
||||
let!(:type_de_champ) { create(:type_de_champ_text) } # goes to another procedure
|
||||
|
||||
let(:params) { { "champ_#{type_de_champ.to_typed_id}" => "value" } }
|
||||
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => "value" } }
|
||||
|
||||
it "filters out the param" do
|
||||
expect(prefill_params_array).to match([])
|
||||
|
@ -72,12 +84,12 @@ RSpec.describe PrefillParams do
|
|||
context "when the type de champ is authorized (#{type_de_champ_type})" do
|
||||
let(:types_de_champ_public) { [{ type: type_de_champ_type }] }
|
||||
let(:type_de_champ) { procedure.published_revision.types_de_champ_public.first }
|
||||
let(:champ_id) { find_champ_by_stable_id(dossier, type_de_champ.stable_id).id }
|
||||
let(:champ) { find_champ_by_stable_id(dossier, type_de_champ.stable_id) }
|
||||
|
||||
let(:params) { { "champ_#{type_de_champ.to_typed_id}" => value } }
|
||||
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => value } }
|
||||
|
||||
it "builds an array of hash(id, value) matching the given params" do
|
||||
expect(prefill_params_array).to match([{ id: champ_id, value: value }])
|
||||
it "builds an array of hash matching the given params" do
|
||||
expect(prefill_params_array).to match([{ id: champ.id }.merge(attributes(champ, value))])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -86,12 +98,12 @@ RSpec.describe PrefillParams do
|
|||
context "when the type de champ is authorized (#{type_de_champ_type})" do
|
||||
let(:types_de_champ_private) { [{ type: type_de_champ_type }] }
|
||||
let(:type_de_champ) { procedure.published_revision.types_de_champ_private.first }
|
||||
let(:champ_id) { find_champ_by_stable_id(dossier, type_de_champ.stable_id).id }
|
||||
let(:champ) { find_champ_by_stable_id(dossier, type_de_champ.stable_id) }
|
||||
|
||||
let(:params) { { "champ_#{type_de_champ.to_typed_id}" => value } }
|
||||
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => value } }
|
||||
|
||||
it "builds an array of hash(id, value) matching the given params" do
|
||||
expect(prefill_params_array).to match([{ id: champ_id, value: value }])
|
||||
it "builds an array of hash matching the given params" do
|
||||
expect(prefill_params_array).to match([{ id: champ.id }.merge(attributes(champ, value))])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -100,7 +112,7 @@ RSpec.describe PrefillParams do
|
|||
let(:types_de_champ_public) { [{ type: type_de_champ_type }] }
|
||||
let(:type_de_champ) { procedure.published_revision.types_de_champ_public.first }
|
||||
|
||||
let(:params) { { "champ_#{type_de_champ.to_typed_id}" => value } }
|
||||
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => value } }
|
||||
|
||||
context "when the type de champ is unauthorized (#{type_de_champ_type})" do
|
||||
it "filters out the param" do
|
||||
|
@ -118,6 +130,7 @@ RSpec.describe PrefillParams do
|
|||
it_behaves_like "a champ public value that is authorized", :iban, "value"
|
||||
it_behaves_like "a champ public value that is authorized", :civilite, "M."
|
||||
it_behaves_like "a champ public value that is authorized", :pays, "FR"
|
||||
it_behaves_like "a champ public value that is authorized", :regions, "03"
|
||||
it_behaves_like "a champ public value that is authorized", :date, "2022-12-22"
|
||||
it_behaves_like "a champ public value that is authorized", :datetime, "2022-12-22T10:30"
|
||||
it_behaves_like "a champ public value that is authorized", :yes_no, "true"
|
||||
|
@ -125,7 +138,28 @@ RSpec.describe PrefillParams do
|
|||
it_behaves_like "a champ public value that is authorized", :checkbox, "true"
|
||||
it_behaves_like "a champ public value that is authorized", :checkbox, "false"
|
||||
it_behaves_like "a champ public value that is authorized", :drop_down_list, "value"
|
||||
it_behaves_like "a champ public value that is authorized", :regions, "03"
|
||||
it_behaves_like "a champ public value that is authorized", :departements, "03"
|
||||
it_behaves_like "a champ public value that is authorized", :communes, ['01', '01457']
|
||||
it_behaves_like "a champ public value that is authorized", :annuaire_education, "0050009H"
|
||||
it_behaves_like "a champ public value that is authorized", :multiple_drop_down_list, ["val1", "val2"]
|
||||
it_behaves_like "a champ public value that is authorized", :dossier_link, "1"
|
||||
it_behaves_like "a champ public value that is authorized", :epci, ['01', '200042935']
|
||||
it_behaves_like "a champ public value that is authorized", :siret, "13002526500013"
|
||||
it_behaves_like "a champ public value that is authorized", :rna, "value"
|
||||
|
||||
context "when the public type de champ is authorized (repetition)" do
|
||||
let(:types_de_champ_public) { [{ type: :repetition, children: [{ type: :text }] }] }
|
||||
let(:type_de_champ) { procedure.published_revision.types_de_champ_public.first }
|
||||
let(:type_de_champ_child) { procedure.published_revision.children_of(type_de_champ).first }
|
||||
let(:type_de_champ_child_value) { "value" }
|
||||
let(:type_de_champ_child_value2) { "value2" }
|
||||
|
||||
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => [{ "champ_#{type_de_champ_child.to_typed_id_for_query}" => type_de_champ_child_value }, { "champ_#{type_de_champ_child.to_typed_id_for_query}" => type_de_champ_child_value2 }] } }
|
||||
|
||||
it "builds an array of hash(id, value) matching the given params" do
|
||||
expect(prefill_params_array).to match([{ id: type_de_champ_child.champ.first.id, value: type_de_champ_child_value }, { id: type_de_champ_child.champ.second.id, value: type_de_champ_child_value2 }])
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like "a champ private value that is authorized", :text, "value"
|
||||
it_behaves_like "a champ private value that is authorized", :textarea, "value"
|
||||
|
@ -136,6 +170,7 @@ RSpec.describe PrefillParams do
|
|||
it_behaves_like "a champ private value that is authorized", :iban, "value"
|
||||
it_behaves_like "a champ private value that is authorized", :civilite, "M."
|
||||
it_behaves_like "a champ private value that is authorized", :pays, "FR"
|
||||
it_behaves_like "a champ private value that is authorized", :regions, "93"
|
||||
it_behaves_like "a champ private value that is authorized", :date, "2022-12-22"
|
||||
it_behaves_like "a champ private value that is authorized", :datetime, "2022-12-22T10:30"
|
||||
it_behaves_like "a champ private value that is authorized", :yes_no, "true"
|
||||
|
@ -144,23 +179,42 @@ RSpec.describe PrefillParams do
|
|||
it_behaves_like "a champ private value that is authorized", :checkbox, "false"
|
||||
it_behaves_like "a champ private value that is authorized", :drop_down_list, "value"
|
||||
it_behaves_like "a champ private value that is authorized", :regions, "93"
|
||||
it_behaves_like "a champ private value that is authorized", :rna, "value"
|
||||
it_behaves_like "a champ private value that is authorized", :siret, "13002526500013"
|
||||
it_behaves_like "a champ private value that is authorized", :departements, "03"
|
||||
it_behaves_like "a champ private value that is authorized", :communes, ['01', '01457']
|
||||
it_behaves_like "a champ private value that is authorized", :annuaire_education, "0050009H"
|
||||
it_behaves_like "a champ private value that is authorized", :multiple_drop_down_list, ["val1", "val2"]
|
||||
it_behaves_like "a champ private value that is authorized", :dossier_link, "1"
|
||||
it_behaves_like "a champ private value that is authorized", :epci, ['01', '200042935']
|
||||
|
||||
context "when the private type de champ is authorized (repetition)" do
|
||||
let(:types_de_champ_private) { [{ type: :repetition, children: [{ type: :text }] }] }
|
||||
let(:type_de_champ) { procedure.published_revision.types_de_champ_private.first }
|
||||
let(:type_de_champ_child) { procedure.published_revision.children_of(type_de_champ).first }
|
||||
let(:type_de_champ_child_value) { "value" }
|
||||
let(:type_de_champ_child_value2) { "value2" }
|
||||
|
||||
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => [{ "champ_#{type_de_champ_child.to_typed_id_for_query}" => type_de_champ_child_value }, { "champ_#{type_de_champ_child.to_typed_id_for_query}" => type_de_champ_child_value2 }] } }
|
||||
|
||||
it "builds an array of hash(id, value) matching the given params" do
|
||||
expect(prefill_params_array).to match([{ id: type_de_champ_child.champ.first.id, value: type_de_champ_child_value }, { id: type_de_champ_child.champ.second.id, value: type_de_champ_child_value2 }])
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like "a champ public value that is unauthorized", :decimal_number, "non decimal string"
|
||||
it_behaves_like "a champ public value that is unauthorized", :integer_number, "non integer string"
|
||||
it_behaves_like "a champ public value that is unauthorized", :number, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :communes, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :dossier_link, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :titre_identite, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :civilite, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :date, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :datetime, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :datetime, "12-22-2022T10:30"
|
||||
it_behaves_like "a champ public value that is unauthorized", :multiple_drop_down_list, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :linked_drop_down_list, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :header_section, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :explication, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :piece_justificative, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :repetition, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :cnaf, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :dgfip, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :pole_emploi, "value"
|
||||
|
@ -170,9 +224,32 @@ RSpec.describe PrefillParams do
|
|||
it_behaves_like "a champ public value that is unauthorized", :pays, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :regions, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :departements, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :siret, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :rna, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :annuaire_education, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :communes, "value"
|
||||
it_behaves_like "a champ public value that is unauthorized", :multiple_drop_down_list, ["value"]
|
||||
|
||||
context "when the public type de champ is unauthorized because of wrong value format (repetition)" do
|
||||
let(:types_de_champ_public) { [{ type: :repetition, children: [{ type: :text }] }] }
|
||||
let(:type_de_champ) { procedure.published_revision.types_de_champ_public.first }
|
||||
let(:type_de_champ_child) { procedure.published_revision.children_of(type_de_champ).first }
|
||||
|
||||
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => "value" } }
|
||||
|
||||
it "builds an array of hash(id, value) matching the given params" do
|
||||
expect(prefill_params_array).to match([])
|
||||
end
|
||||
end
|
||||
|
||||
context "when the public type de champ is unauthorized because of wrong value typed_id (repetition)" do
|
||||
let(:types_de_champ_public) { [{ type: :repetition, children: [{ type: :text }] }] }
|
||||
let(:type_de_champ) { procedure.published_revision.types_de_champ_public.first }
|
||||
let(:type_de_champ_child) { procedure.published_revision.children_of(type_de_champ).first }
|
||||
|
||||
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => ["{\"wrong\":\"value\"}", "{\"wrong\":\"value2\"}"] } }
|
||||
|
||||
it "builds an array of hash(id, value) matching the given params" do
|
||||
expect(prefill_params_array).to match([])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -180,4 +257,10 @@ RSpec.describe PrefillParams do
|
|||
def find_champ_by_stable_id(dossier, stable_id)
|
||||
dossier.champs.joins(:type_de_champ).find_by(types_de_champ: { stable_id: stable_id })
|
||||
end
|
||||
|
||||
def attributes(champ, value)
|
||||
TypesDeChamp::PrefillTypeDeChamp
|
||||
.build(champ.type_de_champ, procedure.active_revision)
|
||||
.to_assignable_attributes(champ, value)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -134,15 +134,15 @@ describe ProcedureRevision do
|
|||
end
|
||||
|
||||
it 'move down' do
|
||||
expect(draft.children_of(type_de_champ_repetition).index(second_child)).to eq(1)
|
||||
|
||||
draft.move_type_de_champ(second_child.stable_id, 2)
|
||||
|
||||
expect(draft.children_of(type_de_champ_repetition).index(second_child)).to eq(2)
|
||||
|
||||
draft.move_type_de_champ(second_child.stable_id, 3)
|
||||
|
||||
expect(draft.children_of(type_de_champ_repetition).index(second_child)).to eq(3)
|
||||
end
|
||||
|
||||
it 'move up' do
|
||||
expect(draft.children_of(type_de_champ_repetition).index(last_child)).to eq(2)
|
||||
expect(draft.children_of(type_de_champ_repetition).index(last_child)).to eq(3)
|
||||
|
||||
draft.move_type_de_champ(last_child.stable_id, 0)
|
||||
|
||||
|
@ -205,13 +205,13 @@ describe ProcedureRevision do
|
|||
|
||||
it 'reorders' do
|
||||
children = draft.children_of(type_de_champ_repetition)
|
||||
expect(children.pluck(:position)).to eq([0, 1, 2])
|
||||
expect(children.pluck(:position)).to eq([0, 1, 2, 3])
|
||||
|
||||
draft.remove_type_de_champ(children[1].stable_id)
|
||||
|
||||
children.reload
|
||||
|
||||
expect(children.pluck(:position)).to eq([0, 1])
|
||||
expect(children.pluck(:position)).to eq([0, 1, 2])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -242,8 +242,8 @@ describe ProcedureRevision do
|
|||
new_draft.remove_type_de_champ(child.stable_id)
|
||||
|
||||
expect { child.reload }.not_to raise_error
|
||||
expect(draft.children_of(type_de_champ_repetition).size).to eq(1)
|
||||
expect(new_draft.children_of(type_de_champ_repetition)).to be_empty
|
||||
expect(draft.children_of(type_de_champ_repetition).size).to eq(2)
|
||||
expect(new_draft.children_of(type_de_champ_repetition).size).to eq(1)
|
||||
end
|
||||
|
||||
it 'can remove the parent only in the new revision' do
|
||||
|
@ -291,7 +291,7 @@ describe ProcedureRevision do
|
|||
let(:procedure) { create(:procedure, :with_repetition) }
|
||||
|
||||
it 'should have the same tdcs with different links' do
|
||||
expect(new_draft.types_de_champ.count).to eq(2)
|
||||
expect(new_draft.types_de_champ.count).to eq(3)
|
||||
expect(new_draft.types_de_champ).to eq(draft.types_de_champ)
|
||||
|
||||
new_repetition, new_child = new_draft.types_de_champ.partition(&:repetition?).map(&:first)
|
||||
|
@ -320,7 +320,7 @@ describe ProcedureRevision do
|
|||
|
||||
it do
|
||||
expect(procedure.revisions.size).to eq(2)
|
||||
expect(draft.revision_types_de_champ.where.not(parent_id: nil).size).to eq(1)
|
||||
expect(draft.revision_types_de_champ.where.not(parent_id: nil).size).to eq(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -639,9 +639,10 @@ describe ProcedureRevision do
|
|||
context 'with a repetition tdc' do
|
||||
let(:procedure) { create(:procedure, :with_repetition) }
|
||||
let!(:parent) { draft.types_de_champ.find(&:repetition?) }
|
||||
let!(:child) { draft.types_de_champ.reject(&:repetition?).first }
|
||||
let!(:first_child) { draft.types_de_champ.reject(&:repetition?).first }
|
||||
let!(:second_child) { draft.types_de_champ.reject(&:repetition?).second }
|
||||
|
||||
it { expect(draft.children_of(parent)).to match([child]) }
|
||||
it { expect(draft.children_of(parent)).to match([first_child, second_child]) }
|
||||
|
||||
context 'with multiple child' do
|
||||
let(:child_position_2) { create(:type_de_champ_text) }
|
||||
|
@ -654,7 +655,7 @@ describe ProcedureRevision do
|
|||
end
|
||||
|
||||
it 'returns the children in order' do
|
||||
expect(draft.children_of(parent)).to eq([child, child_position_1, child_position_2])
|
||||
expect(draft.children_of(parent)).to eq([first_child, second_child, child_position_1, child_position_2])
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -668,13 +669,13 @@ describe ProcedureRevision do
|
|||
before do
|
||||
new_draft
|
||||
.revision_types_de_champ
|
||||
.where(type_de_champ: child)
|
||||
.where(type_de_champ: first_child)
|
||||
.update(type_de_champ: new_child)
|
||||
end
|
||||
|
||||
it 'returns the children regarding the revision' do
|
||||
expect(draft.children_of(parent)).to match([child])
|
||||
expect(new_draft.children_of(parent)).to match([new_child])
|
||||
expect(draft.children_of(parent)).to match([first_child, second_child])
|
||||
expect(new_draft.children_of(parent)).to match([new_child, second_child])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,6 +9,20 @@ describe Procedure do
|
|||
it { expect(subject.without_continuation_mail_template).to be_a(Mails::WithoutContinuationMail) }
|
||||
end
|
||||
|
||||
describe 'compute_dossiers_count' do
|
||||
let(:procedure) { create(:procedure_with_dossiers, dossiers_count: 2, dossiers_count_computed_at: Time.zone.now - Procedure::DOSSIERS_COUNT_EXPIRING) }
|
||||
|
||||
it 'caches estimated_dossiers_count' do
|
||||
procedure.dossiers.each(&:passer_en_construction!)
|
||||
expect { procedure.compute_dossiers_count }.to change(procedure, :estimated_dossiers_count).from(nil).to(2)
|
||||
expect { create(:dossier, procedure: procedure).passer_en_construction! }.not_to change(procedure, :estimated_dossiers_count)
|
||||
|
||||
Timecop.freeze(Time.zone.now + Procedure::DOSSIERS_COUNT_EXPIRING)
|
||||
expect { procedure.compute_dossiers_count }.to change(procedure, :estimated_dossiers_count).from(2).to(3)
|
||||
Timecop.return
|
||||
end
|
||||
end
|
||||
|
||||
describe 'initiated_mail' do
|
||||
let(:procedure) { create(:procedure) }
|
||||
|
||||
|
|
|
@ -4,10 +4,9 @@ describe Stat do
|
|||
describe '.deleted_dossiers_states' do
|
||||
subject { Stat.send(:deleted_dossiers_states) }
|
||||
it 'find counts for columns' do
|
||||
create(:deleted_dossier, dossier_id: create(:dossier).id, state: :termine)
|
||||
create(:deleted_dossier, dossier_id: create(:dossier).id, state: :accepte)
|
||||
create(:deleted_dossier, dossier_id: create(:dossier).id, state: :en_construction, deleted_at: 1.month.ago)
|
||||
create(:deleted_dossier, dossier_id: create(:dossier).id, state: :en_construction, deleted_at: 2.months.ago)
|
||||
create(:deleted_dossier, dossier_id: create(:dossier).id, state: :brouillon, deleted_at: 3.months.ago)
|
||||
create(:deleted_dossier, dossier_id: create(:dossier).id, state: :en_construction, deleted_at: 3.months.ago)
|
||||
create(:deleted_dossier, dossier_id: create(:dossier).id, state: :en_instruction, deleted_at: 3.months.ago)
|
||||
create(:deleted_dossier, dossier_id: create(:dossier).id, state: :accepte, deleted_at: 3.months.ago)
|
||||
|
@ -17,10 +16,10 @@ describe Stat do
|
|||
expect(subject["not_brouillon"]).to eq(8)
|
||||
expect(subject["dossiers_depose_avant_30_jours"]).to eq(1)
|
||||
expect(subject["dossiers_deposes_entre_60_et_30_jours"]).to eq(1)
|
||||
expect(subject["brouillon"]).to eq(1)
|
||||
expect(subject["brouillon"]).to eq(0)
|
||||
expect(subject["en_construction"]).to eq(3)
|
||||
expect(subject["en_instruction"]).to eq(1)
|
||||
expect(subject["termines"]).to eq(3)
|
||||
expect(subject["termines"]).to eq(4)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ describe TypeDeChamp do
|
|||
let(:target_type_champ) { TypeDeChamp.type_champs.fetch(:text) }
|
||||
|
||||
it 'removes the children types de champ' do
|
||||
expect(procedure.draft_revision.children_of(tdc)).to be_empty
|
||||
expect(procedure.draft_revision.reload.children_of(tdc)).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -246,30 +246,36 @@ describe TypeDeChamp do
|
|||
it_behaves_like "a prefillable type de champ", :type_de_champ_datetime
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_civilite
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_pays
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_regions
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_departements
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_communes
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_yes_no
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_checkbox
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_drop_down_list
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_regions
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_repetition
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_annuaire_education
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_multiple_drop_down_list
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_epci
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_dossier_link
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_siret
|
||||
it_behaves_like "a prefillable type de champ", :type_de_champ_rna
|
||||
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_number
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_communes
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_dossier_link
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_titre_identite
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_multiple_drop_down_list
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_linked_drop_down_list
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_header_section
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_explication
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_piece_justificative
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_repetition
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_cnaf
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_dgfip
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_pole_emploi
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_mesri
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_carte
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_address
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_departements
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_siret
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_rna
|
||||
it_behaves_like "a non-prefillable type de champ", :type_de_champ_annuaire_education
|
||||
end
|
||||
|
||||
describe '#normalize_libelle' do
|
||||
it { expect(create(:type_de_champ, :header_section, libelle: " 2.3 Test").libelle).to eq("2.3 Test") }
|
||||
it { expect(create(:type_de_champ, libelle: " fix me ").libelle).to eq("fix me") }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe TypesDeChamp::PrefillAnnuaireEducationTypeDeChamp do
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:type_de_champ) { build(:type_de_champ_annuaire_education, procedure: procedure) }
|
||||
|
||||
describe 'ancestors' do
|
||||
subject { described_class.new(type_de_champ, procedure.active_revision) }
|
||||
|
||||
it { is_expected.to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) }
|
||||
end
|
||||
|
||||
describe '#to_assignable_attributes' do
|
||||
let(:champ) { create(:champ_annuaire_education, type_de_champ: type_de_champ) }
|
||||
subject { described_class.build(type_de_champ, procedure.active_revision).to_assignable_attributes(champ, value) }
|
||||
|
||||
context 'when the value is nil' do
|
||||
let(:value) { nil }
|
||||
it { is_expected.to eq(nil) }
|
||||
end
|
||||
|
||||
context 'when the value is empty' do
|
||||
let(:value) { '' }
|
||||
it { is_expected.to eq(nil) }
|
||||
end
|
||||
|
||||
context 'when the value is present' do
|
||||
let(:value) { '0050009H' }
|
||||
it { is_expected.to match({ id: champ.id, external_id: '0050009H', value: '0050009H' }) }
|
||||
end
|
||||
end
|
||||
end
|
123
spec/models/types_de_champ/prefill_commune_type_de_champ_spec.rb
Normal file
123
spec/models/types_de_champ/prefill_commune_type_de_champ_spec.rb
Normal file
|
@ -0,0 +1,123 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe TypesDeChamp::PrefillCommuneTypeDeChamp do
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:type_de_champ) { build(:type_de_champ_communes, procedure: procedure) }
|
||||
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
|
||||
|
||||
before do
|
||||
allow(Rails).to receive(:cache).and_return(memory_store)
|
||||
Rails.cache.clear
|
||||
end
|
||||
|
||||
before do
|
||||
VCR.insert_cassette('api_geo_departements')
|
||||
VCR.insert_cassette('api_geo_communes')
|
||||
end
|
||||
|
||||
after do
|
||||
VCR.eject_cassette('api_geo_departements')
|
||||
VCR.eject_cassette('api_geo_communes')
|
||||
end
|
||||
|
||||
describe 'ancestors' do
|
||||
subject { described_class.new(type_de_champ, procedure.active_revision) }
|
||||
|
||||
it { is_expected.to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) }
|
||||
end
|
||||
|
||||
describe '#all_possible_values' do
|
||||
let(:expected_values) do
|
||||
departements.map { |departement| "#{departement[:code]} (#{departement[:name]}) : https://geo.api.gouv.fr/communes?codeDepartement=#{departement[:code]}" }
|
||||
end
|
||||
subject(:all_possible_values) { described_class.new(type_de_champ, procedure.active_revision).all_possible_values }
|
||||
|
||||
it { expect(all_possible_values).to match(expected_values) }
|
||||
end
|
||||
|
||||
describe '#example_value' do
|
||||
let(:departement_code) { departements.pick(:code) }
|
||||
let(:commune_code) { APIGeoService.communes(departement_code).pick(:code) }
|
||||
subject(:example_value) { described_class.new(type_de_champ, procedure.active_revision).example_value }
|
||||
|
||||
it { is_expected.to eq([departement_code, commune_code]) }
|
||||
end
|
||||
|
||||
describe '#to_assignable_attributes' do
|
||||
let(:champ) { create(:champ_communes, type_de_champ: type_de_champ) }
|
||||
subject(:to_assignable_attributes) do
|
||||
described_class.build(type_de_champ, procedure.active_revision).to_assignable_attributes(champ, value)
|
||||
end
|
||||
|
||||
context 'when the value is nil' do
|
||||
let(:value) { nil }
|
||||
it { is_expected.to match(nil) }
|
||||
end
|
||||
|
||||
context 'when the value is empty' do
|
||||
let(:value) { '' }
|
||||
it { is_expected.to match(nil) }
|
||||
end
|
||||
|
||||
context 'when the value is a string' do
|
||||
let(:value) { 'hello' }
|
||||
it { is_expected.to match(nil) }
|
||||
end
|
||||
|
||||
context 'when the value is an array of one element' do
|
||||
context 'when the first element is a valid departement code' do
|
||||
let(:value) { ['01'] }
|
||||
it { is_expected.to match({ id: champ.id, code_departement: '01', departement: 'Ain' }) }
|
||||
end
|
||||
|
||||
context 'when the first element is not a valid departement code' do
|
||||
let(:value) { ['totoro'] }
|
||||
it { is_expected.to match(nil) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the value is an array of two elements' do
|
||||
context 'when the first element is a valid departement code' do
|
||||
context 'when the second element is a valid insee code' do
|
||||
let(:value) { ['01', '01457'] }
|
||||
it { is_expected.to match({ id: champ.id, code_departement: '01', departement: 'Ain', external_id: '01457', value: 'Vonnas (01540)' }) }
|
||||
end
|
||||
|
||||
context 'when the second element is not a valid insee code' do
|
||||
let(:value) { ['01', 'totoro'] }
|
||||
it { is_expected.to match(nil) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the first element is not a valid departement code' do
|
||||
let(:value) { ['totoro', '01457'] }
|
||||
it { is_expected.to match(nil) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the value is an array of three or more elements' do
|
||||
context 'when the first element is a valid departement code' do
|
||||
context 'when the second element is a valid insee code' do
|
||||
let(:value) { ['01', '01457', 'hello'] }
|
||||
it { is_expected.to match({ id: champ.id, code_departement: '01', departement: 'Ain', external_id: '01457', value: 'Vonnas (01540)' }) }
|
||||
end
|
||||
|
||||
context 'when the second element is not a valid insee code' do
|
||||
let(:value) { ['01', 'totoro', 'hello'] }
|
||||
it { is_expected.to match(nil) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the first element is not a valid departement code' do
|
||||
let(:value) { ['totoro', '01457', 'hello'] }
|
||||
it { is_expected.to match(nil) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def departements
|
||||
APIGeoService.departements.sort_by { _1[:code] }
|
||||
end
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe TypesDeChamp::PrefillDepartementTypeDeChamp, type: :model do
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:type_de_champ) { build(:type_de_champ_departements, procedure: procedure) }
|
||||
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
|
||||
|
||||
before do
|
||||
allow(Rails).to receive(:cache).and_return(memory_store)
|
||||
Rails.cache.clear
|
||||
end
|
||||
|
||||
describe 'ancestors' do
|
||||
subject { described_class.build(type_de_champ, procedure.active_revision) }
|
||||
|
||||
it { is_expected.to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) }
|
||||
end
|
||||
|
||||
describe '#possible_values', vcr: { cassette_name: 'api_geo_departements' } do
|
||||
let(:expected_values) {
|
||||
"Un <a href=\"https://fr.wikipedia.org/wiki/Num%C3%A9rotation_des_d%C3%A9partements_fran%C3%A7ais\" target=\"_blank\">numéro de département</a><br><a title=\"Toutes les valeurs possibles — Nouvel onglet\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"/procedures/#{procedure.path}/prefill_type_de_champs/#{type_de_champ.id}\">Voir toutes les valeurs possibles</a>"
|
||||
}
|
||||
subject(:possible_values) { described_class.new(type_de_champ, procedure.active_revision).possible_values }
|
||||
|
||||
before { type_de_champ.reload }
|
||||
|
||||
it { expect(possible_values).to match(expected_values) }
|
||||
end
|
||||
end
|
|
@ -2,28 +2,32 @@
|
|||
|
||||
RSpec.describe TypesDeChamp::PrefillDropDownListTypeDeChamp do
|
||||
describe '#possible_values' do
|
||||
subject(:possible_values) { described_class.new(type_de_champ).possible_values }
|
||||
let(:procedure) { create(:procedure) }
|
||||
subject(:possible_values) { described_class.new(type_de_champ, procedure.active_revision).possible_values }
|
||||
|
||||
before { type_de_champ.reload }
|
||||
|
||||
context "when the drop down list accepts 'other'" do
|
||||
let(:type_de_champ) { build(:type_de_champ_drop_down_list, :with_other) }
|
||||
let(:type_de_champ) { build(:type_de_champ_drop_down_list, :with_other, procedure: procedure) }
|
||||
|
||||
it {
|
||||
expect(possible_values).to match(
|
||||
[I18n.t("views.prefill_descriptions.edit.possible_values.drop_down_list_other_html")] + type_de_champ.drop_down_list_enabled_non_empty_options
|
||||
([I18n.t("views.prefill_descriptions.edit.possible_values.drop_down_list_other_html")] + type_de_champ.drop_down_list_enabled_non_empty_options).to_sentence
|
||||
)
|
||||
}
|
||||
end
|
||||
|
||||
context "when the drop down list does not accept 'other'" do
|
||||
let(:type_de_champ) { build(:type_de_champ_drop_down_list) }
|
||||
let(:type_de_champ) { build(:type_de_champ_drop_down_list, procedure:) }
|
||||
|
||||
it { expect(possible_values).to match(type_de_champ.drop_down_list_enabled_non_empty_options) }
|
||||
it { expect(possible_values).to match(type_de_champ.drop_down_list_enabled_non_empty_options.to_sentence) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#example_value' do
|
||||
let(:type_de_champ) { build(:type_de_champ_drop_down_list) }
|
||||
subject(:example_value) { described_class.new(type_de_champ).example_value }
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:type_de_champ) { build(:type_de_champ_drop_down_list, procedure: procedure) }
|
||||
subject(:example_value) { described_class.new(type_de_champ, procedure.active_revision).example_value }
|
||||
|
||||
it { expect(example_value).to eq(type_de_champ.drop_down_list_enabled_non_empty_options.first) }
|
||||
end
|
||||
|
|
106
spec/models/types_de_champ/prefill_epci_type_de_champ_spec.rb
Normal file
106
spec/models/types_de_champ/prefill_epci_type_de_champ_spec.rb
Normal file
|
@ -0,0 +1,106 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe TypesDeChamp::PrefillEpciTypeDeChamp do
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:type_de_champ) { build(:type_de_champ_epci, procedure: procedure) }
|
||||
let(:champ) { create(:champ_epci, type_de_champ: type_de_champ) }
|
||||
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
|
||||
|
||||
before do
|
||||
allow(Rails).to receive(:cache).and_return(memory_store)
|
||||
Rails.cache.clear
|
||||
end
|
||||
|
||||
describe 'ancestors' do
|
||||
subject { described_class.new(type_de_champ, procedure.active_revision) }
|
||||
|
||||
it { is_expected.to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) }
|
||||
end
|
||||
|
||||
describe '#all_possible_values' do
|
||||
let(:expected_values) do
|
||||
departements.map { |departement| "#{departement[:code]} (#{departement[:name]}) : https://geo.api.gouv.fr/epcis?codeDepartement=#{departement[:code]}" }
|
||||
end
|
||||
subject(:all_possible_values) { described_class.new(type_de_champ, procedure.active_revision).all_possible_values }
|
||||
|
||||
before do
|
||||
VCR.insert_cassette('api_geo_departements')
|
||||
VCR.insert_cassette('api_geo_epcis')
|
||||
end
|
||||
|
||||
after do
|
||||
VCR.eject_cassette('api_geo_departements')
|
||||
VCR.eject_cassette('api_geo_epcis')
|
||||
end
|
||||
|
||||
it { expect(all_possible_values).to match(expected_values) }
|
||||
end
|
||||
|
||||
describe '#example_value' do
|
||||
let(:departement_code) { departements.pick(:code) }
|
||||
let(:epci_code) { APIGeoService.epcis(departement_code).pick(:code) }
|
||||
subject(:example_value) { described_class.new(type_de_champ, procedure.active_revision).example_value }
|
||||
|
||||
before do
|
||||
VCR.insert_cassette('api_geo_departements')
|
||||
VCR.insert_cassette('api_geo_epcis')
|
||||
end
|
||||
|
||||
after do
|
||||
VCR.eject_cassette('api_geo_departements')
|
||||
VCR.eject_cassette('api_geo_epcis')
|
||||
end
|
||||
|
||||
it { is_expected.to eq([departement_code, epci_code]) }
|
||||
end
|
||||
|
||||
describe '#to_assignable_attributes' do
|
||||
subject(:to_assignable_attributes) { described_class.build(type_de_champ, procedure.active_revision).to_assignable_attributes(champ, value) }
|
||||
|
||||
shared_examples "a transformation to" do |code_departement, value|
|
||||
it { is_expected.to match({ code_departement: code_departement, value: value, id: champ.id }) }
|
||||
end
|
||||
|
||||
context 'when the value is nil' do
|
||||
let(:value) { nil }
|
||||
|
||||
it_behaves_like "a transformation to", nil, nil
|
||||
end
|
||||
|
||||
context 'when the value is empty' do
|
||||
let(:value) { '' }
|
||||
|
||||
it_behaves_like "a transformation to", nil, nil
|
||||
end
|
||||
|
||||
context 'when the value is a string' do
|
||||
let(:value) { 'hello' }
|
||||
|
||||
it_behaves_like "a transformation to", nil, nil
|
||||
end
|
||||
|
||||
context 'when the value is an array of one element' do
|
||||
let(:value) { ['01'] }
|
||||
|
||||
it_behaves_like "a transformation to", '01', nil
|
||||
end
|
||||
|
||||
context 'when the value is an array of two elements' do
|
||||
let(:value) { ['01', '200042935'] }
|
||||
|
||||
it_behaves_like "a transformation to", '01', '200042935'
|
||||
end
|
||||
|
||||
context 'when the value is an array of three or more elements' do
|
||||
let(:value) { ['01', '200042935', 'hello'] }
|
||||
|
||||
it_behaves_like "a transformation to", '01', '200042935'
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def departements
|
||||
APIGeoService.departements.sort_by { |departement| departement[:code] }
|
||||
end
|
||||
end
|
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe TypesDeChamp::PrefillMultipleDropDownListTypeDeChamp do
|
||||
let(:procedure) { create(:procedure) }
|
||||
|
||||
describe 'ancestors' do
|
||||
subject { described_class.new(build(:type_de_champ_multiple_drop_down_list, procedure: procedure), procedure.active_revision) }
|
||||
|
||||
it { is_expected.to be_kind_of(TypesDeChamp::PrefillDropDownListTypeDeChamp) }
|
||||
end
|
||||
|
||||
describe '#example_value' do
|
||||
let(:type_de_champ) { build(:type_de_champ_multiple_drop_down_list, drop_down_list_value: drop_down_list_value, procedure: procedure) }
|
||||
subject(:example_value) { described_class.new(type_de_champ, procedure.active_revision).example_value }
|
||||
|
||||
context 'when the multiple drop down list has no option' do
|
||||
let(:drop_down_list_value) { "" }
|
||||
|
||||
it { expect(example_value).to eq(nil) }
|
||||
end
|
||||
|
||||
context 'when the multiple drop down list only has one option' do
|
||||
let(:drop_down_list_value) { "value" }
|
||||
|
||||
it { expect(example_value).to eq("value") }
|
||||
end
|
||||
|
||||
context 'when the multiple drop down list has two options or more' do
|
||||
let(:drop_down_list_value) { "value1\r\nvalue2\r\nvalue3" }
|
||||
|
||||
it { expect(example_value).to eq(["value1", "value2"]) }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,17 +1,22 @@
|
|||
|
||||
RSpec.describe TypesDeChamp::PrefillPaysTypeDeChamp, type: :model do
|
||||
let(:type_de_champ) { build(:type_de_champ_pays) }
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:type_de_champ) { build(:type_de_champ_pays, procedure: procedure) }
|
||||
|
||||
describe 'ancestors' do
|
||||
subject { described_class.build(type_de_champ, procedure.active_revision) }
|
||||
|
||||
it { is_expected.to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) }
|
||||
end
|
||||
|
||||
describe '#possible_values' do
|
||||
let(:expected_values) { APIGeoService.countries.sort_by { |country| country[:code] }.map { |country| "#{country[:code]} (#{country[:name]})" } }
|
||||
subject(:possible_values) { described_class.new(type_de_champ).possible_values }
|
||||
let(:expected_values) { "Un <a href=\"https://en.wikipedia.org/wiki/ISO_3166-2\" target=\"_blank\" rel=\"noopener noreferrer\">code pays ISO 3166-2</a><br><a title=\"Toutes les valeurs possibles — Nouvel onglet\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"/procedures/#{procedure.path}/prefill_type_de_champs/#{type_de_champ.id}\">Voir toutes les valeurs possibles</a>" }
|
||||
subject(:possible_values) { described_class.new(type_de_champ, procedure.active_revision).possible_values }
|
||||
|
||||
it { expect(possible_values).to match(expected_values) }
|
||||
end
|
||||
before { type_de_champ.reload }
|
||||
|
||||
describe '#example_value' do
|
||||
subject(:example_value) { described_class.new(type_de_champ).example_value }
|
||||
|
||||
it { expect(example_value).to eq(APIGeoService.countries.sort_by { |country| country[:code] }.first[:code]) }
|
||||
it {
|
||||
expect(possible_values).to match(expected_values)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe TypesDeChamp::PrefillRegionTypeDeChamp, type: :model do
|
||||
let(:type_de_champ) { build(:type_de_champ_regions) }
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:type_de_champ) { create(:type_de_champ_regions, procedure: procedure) }
|
||||
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
|
||||
|
||||
before do
|
||||
|
@ -10,15 +11,19 @@ RSpec.describe TypesDeChamp::PrefillRegionTypeDeChamp, type: :model do
|
|||
end
|
||||
|
||||
describe 'ancestors' do
|
||||
subject { described_class.build(type_de_champ) }
|
||||
subject { described_class.build(type_de_champ, procedure.active_revision) }
|
||||
|
||||
it { is_expected.to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) }
|
||||
end
|
||||
|
||||
describe '#possible_values', vcr: { cassette_name: 'api_geo_regions' } do
|
||||
let(:expected_values) { APIGeoService.regions.sort_by { |region| region[:code] }.map { |region| "#{region[:code]} (#{region[:name]})" } }
|
||||
subject(:possible_values) { described_class.new(type_de_champ).possible_values }
|
||||
let(:expected_values) { "Un <a href=\"https://fr.wikipedia.org/wiki/R%C3%A9gion_fran%C3%A7aise\" target=\"_blank\" rel=\"noopener noreferrer\">code INSEE de région</a><br><a title=\"Toutes les valeurs possibles — Nouvel onglet\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"/procedures/#{procedure.path}/prefill_type_de_champs/#{type_de_champ.id}\">Voir toutes les valeurs possibles</a>" }
|
||||
subject(:possible_values) { described_class.new(type_de_champ, procedure.active_revision).possible_values }
|
||||
|
||||
it { expect(possible_values).to match(expected_values) }
|
||||
before { type_de_champ.reload }
|
||||
|
||||
it {
|
||||
expect(possible_values).to eq(expected_values)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe TypesDeChamp::PrefillRepetitionTypeDeChamp, type: :model, vcr: { cassette_name: 'api_geo_regions' } do
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:type_de_champ) { build(:type_de_champ_repetition, :with_types_de_champ, :with_region_types_de_champ, procedure: procedure) }
|
||||
let(:champ) { create(:champ_repetition, type_de_champ: type_de_champ) }
|
||||
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(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
|
||||
|
||||
before do
|
||||
allow(Rails).to receive(:cache).and_return(memory_store)
|
||||
Rails.cache.clear
|
||||
end
|
||||
|
||||
describe 'ancestors' do
|
||||
subject { described_class.build(type_de_champ, procedure.active_revision) }
|
||||
|
||||
it { is_expected.to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) }
|
||||
end
|
||||
|
||||
describe '#possible_values' do
|
||||
subject(:possible_values) { described_class.new(type_de_champ, procedure.active_revision).possible_values }
|
||||
let(:expected_value) {
|
||||
"Un tableau de dictionnaires avec les valeurs possibles pour chaque champ de la répétition.</br><ul><li>champ_#{text_repetition.to_typed_id_for_query}: Un texte court<br></li><li>champ_#{integer_repetition.to_typed_id_for_query}: Un nombre entier<br></li><li>champ_#{region_repetition.to_typed_id_for_query}: Un <a href=\"https://fr.wikipedia.org/wiki/R%C3%A9gion_fran%C3%A7aise\" target=\"_blank\" rel=\"noopener noreferrer\">code INSEE de région</a><br><a title=\"Toutes les valeurs possibles — Nouvel onglet\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"/procedures/#{procedure.path}/prefill_type_de_champs/#{region_repetition.id}\">Voir toutes les valeurs possibles</a></li></ul>"
|
||||
}
|
||||
|
||||
it {
|
||||
expect(possible_values).to eq(expected_value)
|
||||
}
|
||||
end
|
||||
|
||||
describe '#example_value' do
|
||||
subject(:example_value) { described_class.new(type_de_champ, procedure.active_revision).example_value }
|
||||
let(:expected_value) { [{ "champ_#{text_repetition.to_typed_id_for_query}" => "Texte court", "champ_#{integer_repetition.to_typed_id_for_query}" => "42", "champ_#{region_repetition.to_typed_id_for_query}" => "53" }, { "champ_#{text_repetition.to_typed_id_for_query}" => "Texte court", "champ_#{integer_repetition.to_typed_id_for_query}" => "42", "champ_#{region_repetition.to_typed_id_for_query}" => "53" }] }
|
||||
|
||||
it { expect(example_value).to eq(expected_value) }
|
||||
end
|
||||
|
||||
describe '#to_assignable_attributes' do
|
||||
subject(:to_assignable_attributes) { described_class.build(type_de_champ, procedure.active_revision).to_assignable_attributes(champ, value) }
|
||||
|
||||
context 'when the value is nil' do
|
||||
let(:value) { nil }
|
||||
it { is_expected.to match([]) }
|
||||
end
|
||||
|
||||
context 'when the value is empty' do
|
||||
let(:value) { '' }
|
||||
it { is_expected.to match([]) }
|
||||
end
|
||||
|
||||
context 'when the value is a string' do
|
||||
let(:value) { 'hello' }
|
||||
it { is_expected.to match([]) }
|
||||
end
|
||||
|
||||
context 'when the value is an array with wrong keys' do
|
||||
let(:value) { ["{\"blabla\":\"value\"}", "{\"blabla\":\"value2\"}"] }
|
||||
|
||||
it { is_expected.to match([]) }
|
||||
end
|
||||
|
||||
context 'when the value is an array with some wrong keys' do
|
||||
let(:value) { [{ "champ_#{text_repetition.to_typed_id_for_query}" => "value", "blabla" => "value2" }, { "champ_#{integer_repetition.to_typed_id_for_query}" => "value3" }, { "blabla" => "false" }] }
|
||||
|
||||
it { is_expected.to match([[{ id: text_repetition.champ.first.id, value: "value" }], [{ id: integer_repetition.champ.second.id, value: "value3" }]]) }
|
||||
end
|
||||
|
||||
context 'when the value is an array with right keys' do
|
||||
let(:value) { [{ "champ_#{text_repetition.to_typed_id_for_query}" => "value" }, { "champ_#{text_repetition.to_typed_id_for_query}" => "value2" }] }
|
||||
|
||||
it { is_expected.to match([[{ id: text_repetition.champ.first.id, value: "value" }], [{ id: text_repetition.champ.second.id, value: "value2" }]]) }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,36 +1,77 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe TypesDeChamp::PrefillTypeDeChamp, type: :model do
|
||||
include ActionView::Helpers::UrlHelper
|
||||
include ApplicationHelper
|
||||
|
||||
let(:procedure) { create(:procedure) }
|
||||
|
||||
describe '.build' do
|
||||
subject(:built) { described_class.build(type_de_champ) }
|
||||
subject(:built) { described_class.build(type_de_champ, procedure.active_revision) }
|
||||
|
||||
context 'when the type de champ is a drop_down_list' do
|
||||
let(:type_de_champ) { build(:type_de_champ_drop_down_list) }
|
||||
let(:type_de_champ) { build(:type_de_champ_drop_down_list, procedure: procedure) }
|
||||
|
||||
it { expect(built).to be_kind_of(TypesDeChamp::PrefillDropDownListTypeDeChamp) }
|
||||
end
|
||||
|
||||
context 'when the type de champ is a multiple_drop_down_list' do
|
||||
let(:type_de_champ) { build(:type_de_champ_multiple_drop_down_list, procedure: procedure) }
|
||||
|
||||
it { expect(built).to be_kind_of(TypesDeChamp::PrefillMultipleDropDownListTypeDeChamp) }
|
||||
end
|
||||
|
||||
context 'when the type de champ is a pays' do
|
||||
let(:type_de_champ) { build(:type_de_champ_pays) }
|
||||
let(:type_de_champ) { build(:type_de_champ_pays, procedure: procedure) }
|
||||
|
||||
it { expect(built).to be_kind_of(TypesDeChamp::PrefillPaysTypeDeChamp) }
|
||||
end
|
||||
|
||||
context 'when the type de champ is a regions' do
|
||||
let(:type_de_champ) { build(:type_de_champ_regions) }
|
||||
let(:type_de_champ) { build(:type_de_champ_regions, procedure: procedure) }
|
||||
|
||||
it { expect(built).to be_kind_of(TypesDeChamp::PrefillRegionTypeDeChamp) }
|
||||
end
|
||||
|
||||
context 'when the type de champ is a repetition' do
|
||||
let(:type_de_champ) { build(:type_de_champ_repetition, procedure: procedure) }
|
||||
|
||||
it { expect(built).to be_kind_of(TypesDeChamp::PrefillRepetitionTypeDeChamp) }
|
||||
end
|
||||
|
||||
context 'when the type de champ is a departements' do
|
||||
let(:type_de_champ) { build(:type_de_champ_departements, procedure: procedure) }
|
||||
|
||||
it { expect(built).to be_kind_of(TypesDeChamp::PrefillDepartementTypeDeChamp) }
|
||||
end
|
||||
|
||||
context 'when the type de champ is a communes' do
|
||||
let(:type_de_champ) { build(:type_de_champ_communes) }
|
||||
|
||||
it { expect(built).to be_kind_of(TypesDeChamp::PrefillCommuneTypeDeChamp) }
|
||||
end
|
||||
|
||||
context 'when the type de champ is a epci' do
|
||||
let(:type_de_champ) { build(:type_de_champ_epci, procedure: procedure) }
|
||||
|
||||
it { expect(built).to be_kind_of(TypesDeChamp::PrefillEpciTypeDeChamp) }
|
||||
end
|
||||
|
||||
context 'when the type de champ is an annuaire_education' do
|
||||
let(:type_de_champ) { build(:type_de_champ_annuaire_education) }
|
||||
|
||||
it { expect(built).to be_kind_of(TypesDeChamp::PrefillAnnuaireEducationTypeDeChamp) }
|
||||
end
|
||||
|
||||
context 'when any other type de champ' do
|
||||
let(:type_de_champ) { build(:type_de_champ_date) }
|
||||
let(:type_de_champ) { build(:type_de_champ_date, procedure: procedure) }
|
||||
|
||||
it { expect(built).to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '.wrap' do
|
||||
subject(:wrapped) { described_class.wrap([build(:type_de_champ_drop_down_list), build(:type_de_champ_email)]) }
|
||||
subject(:wrapped) { described_class.wrap([build(:type_de_champ_drop_down_list, procedure: procedure), build(:type_de_champ_email, procedure: procedure)], procedure.active_revision) }
|
||||
|
||||
it 'wraps the collection' do
|
||||
expect(wrapped.first).to be_kind_of(TypesDeChamp::PrefillDropDownListTypeDeChamp)
|
||||
|
@ -39,51 +80,81 @@ RSpec.describe TypesDeChamp::PrefillTypeDeChamp, type: :model do
|
|||
end
|
||||
|
||||
describe '#possible_values' do
|
||||
subject(:possible_values) { described_class.build(type_de_champ).possible_values }
|
||||
|
||||
context 'when the type de champ is not prefillable' do
|
||||
let(:type_de_champ) { build(:type_de_champ_mesri) }
|
||||
|
||||
it { expect(possible_values).to be_empty }
|
||||
end
|
||||
let(:built) { described_class.build(type_de_champ, procedure.active_revision) }
|
||||
subject(:possible_values) { built.possible_values }
|
||||
|
||||
context 'when the type de champ is prefillable' do
|
||||
let(:type_de_champ) { build(:type_de_champ_email) }
|
||||
context 'when the type de champ has a description' do
|
||||
let(:type_de_champ) { build(:type_de_champ_text) }
|
||||
|
||||
it { expect(possible_values).to match([]) }
|
||||
it { expect(possible_values).to include(I18n.t("views.prefill_descriptions.edit.possible_values.#{type_de_champ.type_champ}_html")) }
|
||||
end
|
||||
|
||||
context 'when the type de champ does not have a description' do
|
||||
let(:type_de_champ) { build(:type_de_champ_mesri) }
|
||||
|
||||
it { expect(possible_values).not_to include(I18n.t("views.prefill_descriptions.edit.possible_values.#{type_de_champ.type_champ}_html")) }
|
||||
end
|
||||
|
||||
describe 'too many possible values or not' do
|
||||
let!(:procedure) { create(:procedure, :with_drop_down_list) }
|
||||
let(:type_de_champ) { procedure.draft_types_de_champ_public.first }
|
||||
let(:link_to_all_possible_values) {
|
||||
link_to(
|
||||
I18n.t("views.prefill_descriptions.edit.possible_values.link.text"),
|
||||
Rails.application.routes.url_helpers.prefill_type_de_champ_path(procedure.path, type_de_champ),
|
||||
title: new_tab_suffix(I18n.t("views.prefill_descriptions.edit.possible_values.link.title")),
|
||||
**external_link_attributes
|
||||
)
|
||||
}
|
||||
|
||||
context 'when there is too many possible values' do
|
||||
before { type_de_champ.drop_down_options = (1..described_class::POSSIBLE_VALUES_THRESHOLD + 1).map(&:to_s) }
|
||||
|
||||
it { expect(possible_values).to include(link_to_all_possible_values) }
|
||||
|
||||
it { expect(possible_values).not_to include(built.all_possible_values.to_sentence) }
|
||||
end
|
||||
|
||||
context 'when there is not too many possible values' do
|
||||
before { type_de_champ.drop_down_options = (1..described_class::POSSIBLE_VALUES_THRESHOLD - 1).map(&:to_s) }
|
||||
|
||||
it { expect(possible_values).not_to include(link_to_all_possible_values) }
|
||||
|
||||
it { expect(possible_values).to include(built.all_possible_values.to_sentence) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the type de champ is not prefillable' do
|
||||
let(:type_de_champ) { build(:type_de_champ_mesri, procedure: procedure) }
|
||||
|
||||
it { expect(possible_values).to be_empty }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#example_value' do
|
||||
subject(:example_value) { described_class.build(type_de_champ).example_value }
|
||||
subject(:example_value) { described_class.build(type_de_champ, procedure.active_revision).example_value }
|
||||
|
||||
context 'when the type de champ is not prefillable' do
|
||||
let(:type_de_champ) { build(:type_de_champ_mesri) }
|
||||
let(:type_de_champ) { build(:type_de_champ_mesri, procedure: procedure) }
|
||||
|
||||
it { expect(example_value).to be_nil }
|
||||
end
|
||||
|
||||
context 'when the type de champ is prefillable' do
|
||||
let(:type_de_champ) { build(:type_de_champ_email) }
|
||||
let(:type_de_champ) { build(:type_de_champ_email, procedure: procedure) }
|
||||
|
||||
it { expect(example_value).to eq(I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#too_many_possible_values?' do
|
||||
let(:type_de_champ) { build(:type_de_champ_drop_down_list) }
|
||||
subject(:too_many_possible_values) { described_class.build(type_de_champ).too_many_possible_values? }
|
||||
describe '#to_assignable_attributes' do
|
||||
let(:type_de_champ) { build(:type_de_champ_email, procedure: procedure) }
|
||||
let(:champ) { build(:champ, type_de_champ: type_de_champ) }
|
||||
let(:value) { "any@email.org" }
|
||||
subject(:to_assignable_attributes) { described_class.build(type_de_champ, procedure.active_revision).to_assignable_attributes(champ, value) }
|
||||
|
||||
context 'when there are too many possible values' do
|
||||
before { type_de_champ.drop_down_options = (1..described_class::POSSIBLE_VALUES_THRESHOLD + 1).map(&:to_s) }
|
||||
|
||||
it { expect(too_many_possible_values).to eq(true) }
|
||||
end
|
||||
|
||||
context 'when there are not too many possible values' do
|
||||
before { type_de_champ.drop_down_options = (1..described_class::POSSIBLE_VALUES_THRESHOLD).map(&:to_s) }
|
||||
|
||||
it { expect(too_many_possible_values).to eq(false) }
|
||||
end
|
||||
it { is_expected.to match({ id: champ.id, value: value }) }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,11 +15,16 @@ describe APIEntrepriseService do
|
|||
before do
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}/)
|
||||
.to_return(body: etablissements_body, status: etablissements_status)
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siret[0..8]}/)
|
||||
.to_return(body: entreprises_body, status: entreprises_status)
|
||||
end
|
||||
|
||||
let(:siret) { '41816609600051' }
|
||||
let(:raison_sociale) { "OCTO-TECHNOLOGY" }
|
||||
let(:etablissements_status) { 200 }
|
||||
let(:etablissements_body) { File.read('spec/fixtures/files/api_entreprise/etablissements.json') }
|
||||
let(:entreprises_status) { 200 }
|
||||
let(:entreprises_body) { File.read('spec/fixtures/files/api_entreprise/entreprises.json') }
|
||||
let(:valid_token) { "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" }
|
||||
let(:procedure) { create(:procedure, api_entreprise_token: valid_token) }
|
||||
let(:dossier) { create(:dossier, procedure: procedure) }
|
||||
|
@ -35,6 +40,10 @@ describe APIEntrepriseService do
|
|||
expect(subject[:siret]).to eq(siret)
|
||||
end
|
||||
|
||||
it 'should fetch entreprise params' do
|
||||
expect(subject[:entreprise_raison_sociale]).to eq(raison_sociale)
|
||||
end
|
||||
|
||||
it_behaves_like 'schedule fetch of all etablissement params'
|
||||
end
|
||||
|
||||
|
|
|
@ -36,13 +36,36 @@ describe APIGeoService do
|
|||
|
||||
describe 'departements', vcr: { cassette_name: 'api_geo_departements' } do
|
||||
it 'return sorted results' do
|
||||
expect(APIGeoService.departements.size).to eq(102)
|
||||
expect(APIGeoService.departements.size).to eq(110)
|
||||
expect(APIGeoService.departements.first).to eq(code: '99', name: 'Etranger')
|
||||
expect(APIGeoService.departements.second).to eq(code: '01', name: 'Ain')
|
||||
expect(APIGeoService.departements.last).to eq(code: '976', name: 'Mayotte')
|
||||
expect(APIGeoService.departements.last).to eq(code: '989', name: 'Île de Clipperton')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'communes', vcr: { cassette_name: 'api_geo_communes' } do
|
||||
it 'return sorted results' do
|
||||
expect(APIGeoService.communes('01').size).to eq(393)
|
||||
expect(APIGeoService.communes('01').first).to eq(code: '01004', name: 'Ambérieu-en-Bugey', postal_codes: ['01500'])
|
||||
expect(APIGeoService.communes('01').last).to eq(code: '01457', name: 'Vonnas', postal_codes: ['01540'])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'commune_name', vcr: { cassette_name: 'api_geo_communes' } do
|
||||
subject { APIGeoService.commune_name('01', '01457') }
|
||||
it { is_expected.to eq('Vonnas') }
|
||||
end
|
||||
|
||||
describe 'commune_code', vcr: { cassette_name: 'api_geo_communes' } do
|
||||
subject { APIGeoService.commune_code('01', 'Vonnas') }
|
||||
it { is_expected.to eq('01457') }
|
||||
end
|
||||
|
||||
describe 'commune_postal_codes', vcr: { cassette_name: 'api_geo_communes' } do
|
||||
subject { APIGeoService.commune_postal_codes('01', '01457') }
|
||||
it { is_expected.to eq(['01540']) }
|
||||
end
|
||||
|
||||
describe 'epcis', vcr: { cassette_name: 'api_geo_epcis' } do
|
||||
it 'return sorted results' do
|
||||
expect(APIGeoService.epcis('01').size).to eq(17)
|
||||
|
|
|
@ -17,7 +17,7 @@ describe DemarchesPubliquesExportService do
|
|||
typeOrganisme: "association"
|
||||
},
|
||||
cadreJuridiqueUrl: "un cadre juridique important",
|
||||
demarcheUrl: nil,
|
||||
demarcheUrl: Rails.application.routes.url_helpers.commencer_url(path: procedure.path),
|
||||
dpoUrl: nil,
|
||||
noticeUrl: nil,
|
||||
siteWebUrl: "https://mon-site.gouv",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
describe InstructeursImportService do
|
||||
describe '#import' do
|
||||
describe '#import_groupes' do
|
||||
let(:procedure) { create(:procedure) }
|
||||
|
||||
let(:procedure_groupes) do
|
||||
|
@ -9,7 +9,7 @@ describe InstructeursImportService do
|
|||
.to_h
|
||||
end
|
||||
|
||||
subject { described_class.import(procedure, lines) }
|
||||
subject { described_class.import_groupes(procedure, lines) }
|
||||
|
||||
context 'nominal case' do
|
||||
let(:lines) do
|
||||
|
@ -20,8 +20,8 @@ describe InstructeursImportService do
|
|||
]
|
||||
end
|
||||
|
||||
it 'imports' do
|
||||
errors = subject
|
||||
it 'imports groupes' do
|
||||
_, errors = subject
|
||||
|
||||
expect(procedure_groupes.keys).to contain_exactly("Auvergne Rhone-Alpes", "Occitanie", "défaut")
|
||||
expect(procedure_groupes["Auvergne Rhone-Alpes"]).to contain_exactly("john@lennon.fr")
|
||||
|
@ -63,7 +63,7 @@ describe InstructeursImportService do
|
|||
end
|
||||
|
||||
it 'ignores or corrects' do
|
||||
errors = subject
|
||||
_, errors = subject
|
||||
|
||||
expect(procedure_groupes.keys).to contain_exactly("Occitanie", "défaut")
|
||||
expect(procedure_groupes["Occitanie"]).to contain_exactly("paul@mccartney.uk", "ringo@starr.uk")
|
||||
|
@ -117,7 +117,7 @@ describe InstructeursImportService do
|
|||
end
|
||||
|
||||
it 'ignores instructeur' do
|
||||
errors = subject
|
||||
_, errors = subject
|
||||
|
||||
expect(procedure_groupes.keys).to contain_exactly("défaut")
|
||||
expect(procedure_groupes["défaut"]).to be_empty
|
||||
|
@ -126,4 +126,21 @@ describe InstructeursImportService do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#import_instructeurs' do
|
||||
let(:procedure_non_routee) { create(:procedure) }
|
||||
|
||||
subject { described_class.import_instructeurs(procedure_non_routee, emails) }
|
||||
|
||||
context 'nominal case' do
|
||||
let(:emails) { [{ "email" => "john@lennon.fr" }, { "email" => "paul@mccartney.uk" }, { "email" => "ringo@starr.uk" }] }
|
||||
|
||||
it 'imports instructeurs' do
|
||||
_, errors = subject
|
||||
expect(procedure_non_routee.defaut_groupe_instructeur.instructeurs.pluck(:email)).to contain_exactly("john@lennon.fr", "paul@mccartney.uk", "ringo@starr.uk")
|
||||
|
||||
expect(errors).to match_array([])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
shared_examples "the user has got a prefilled dossier, owned by themselves" do
|
||||
scenario "the user has got a prefilled dossier, owned by themselves" do
|
||||
siret = '41816609600051'
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}/)
|
||||
.to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/etablissements.json'))
|
||||
|
||||
expect(dossier.user).to eq(user)
|
||||
|
||||
expect(page).to have_current_path siret_dossier_path(procedure.dossiers.last)
|
||||
fill_in 'Numéro SIRET', with: siret
|
||||
fill_in 'Numéro SIRET', with: siret_value
|
||||
click_on 'Valider'
|
||||
|
||||
expect(page).to have_current_path(etablissement_dossier_path(dossier))
|
||||
|
@ -18,6 +14,18 @@ shared_examples "the user has got a prefilled dossier, owned by themselves" do
|
|||
expect(page).to have_field(type_de_champ_text.libelle, with: text_value)
|
||||
expect(page).to have_field(type_de_champ_phone.libelle, with: phone_value)
|
||||
expect(page).to have_css('label', text: type_de_champ_phone.libelle)
|
||||
expect(page).to have_field(type_de_champ_rna.libelle, with: rna_value)
|
||||
expect(page).to have_field(type_de_champ_siret.libelle, with: siret_value)
|
||||
expect(page).to have_css('h3', text: type_de_champ_repetition.libelle)
|
||||
expect(page).to have_field(text_repetition_libelle, with: text_repetition_value)
|
||||
expect(page).to have_field(integer_repetition_libelle, with: integer_repetition_value)
|
||||
expect(page).to have_field(type_de_champ_datetime.libelle, with: datetime_value)
|
||||
expect(page).to have_css('label', text: type_de_champ_multiple_drop_down_list.libelle)
|
||||
expect(page).to have_content(multiple_drop_down_list_values.first)
|
||||
expect(page).to have_content(multiple_drop_down_list_values.last)
|
||||
expect(page).to have_field(type_de_champ_epci.libelle, with: epci_value.last)
|
||||
expect(page).to have_field(type_de_champ_dossier_link.libelle, with: dossier_link_value)
|
||||
expect(page).to have_selector("input[value='Vonnas (01540)']")
|
||||
expect(page).to have_content(annuaire_education_value.last)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,7 +14,22 @@ describe 'As an administrateur I wanna clone a procedure', js: true do
|
|||
published_at: Time.zone.now)
|
||||
login_as administrateur.user, scope: :user
|
||||
end
|
||||
context 'Visit all admin procedures' do
|
||||
let(:download_dir) { Rails.root.join('tmp/capybara') }
|
||||
let(:download_file_pattern) { download_dir.join('*.xlsx') }
|
||||
|
||||
scenario do
|
||||
Dir[download_file_pattern].map { File.delete(_1) }
|
||||
visit all_admin_procedures_path
|
||||
|
||||
click_on "Exporter les résultats"
|
||||
Timeout.timeout(Capybara.default_max_wait_time,
|
||||
Timeout::Error,
|
||||
"File download timeout! can't download procedure/all.xlsx") do
|
||||
sleep 0.1 until !Dir[download_file_pattern].empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
context 'Cloning a procedure owned by the current admin' do
|
||||
scenario do
|
||||
visit admin_procedures_path
|
||||
|
|
|
@ -63,7 +63,7 @@ describe 'Inviting an expert:', js: true do
|
|||
click_on 'Avis externes'
|
||||
|
||||
expect(page).to have_content(answered_avis.expert.email)
|
||||
answered_avis.answer.split("\n").each do |answer_line|
|
||||
answered_avis.answer.split("\n").map { |line| line.gsub("- ", "") }.map do |answer_line|
|
||||
expect(page).to have_content(answer_line)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@ describe 'As an instructeur', js: true do
|
|||
end
|
||||
|
||||
scenario 'I can register' do
|
||||
confirmation_email = open_email(instructeur_email)
|
||||
confirmation_email = emails_sent_to(instructeur_email).first
|
||||
token_params = confirmation_email.body.match(/token=[^"]+/)
|
||||
|
||||
visit "users/activate?#{token_params}"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
describe "procedure filters" do
|
||||
let(:instructeur) { create(:instructeur) }
|
||||
let(:procedure) { create(:procedure, :published, :with_type_de_champ, instructeurs: [instructeur]) }
|
||||
let(:procedure) { create(:procedure, :published, :with_type_de_champ, :with_departement, :with_region, instructeurs: [instructeur]) }
|
||||
let!(:type_de_champ) { procedure.active_revision.types_de_champ_public.first }
|
||||
let!(:new_unfollow_dossier) { create(:dossier, procedure: procedure, state: Dossier.states.fetch(:en_instruction)) }
|
||||
let!(:champ) { Champ.find_by(type_de_champ_id: type_de_champ.id, dossier_id: new_unfollow_dossier.id) }
|
||||
|
@ -94,6 +94,44 @@ describe "procedure filters" do
|
|||
click_button "Ajouter le filtre"
|
||||
end
|
||||
|
||||
describe 'with a vcr cached cassette' do
|
||||
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
|
||||
|
||||
before do
|
||||
allow(Rails).to receive(:cache).and_return(memory_store)
|
||||
Rails.cache.clear
|
||||
end
|
||||
|
||||
scenario "should be able to find by departements with custom enum lookup", js: true, vcr: { cassette_name: 'api_geo_departements' } do
|
||||
departement_champ = new_unfollow_dossier.champs.find(&:departement?)
|
||||
departement_champ.update!(value: 'Oise', external_id: '60')
|
||||
departement_champ.reload
|
||||
champ_select_value = "#{departement_champ.external_id} – #{departement_champ.value}"
|
||||
|
||||
click_on 'Sélectionner un filtre'
|
||||
select departement_champ.libelle, from: "Colonne"
|
||||
find("select#value", visible: true)
|
||||
select champ_select_value, from: "Valeur"
|
||||
click_button "Ajouter le filtre"
|
||||
find("select#value", visible: false) # w8 for filter to be applied
|
||||
expect(page).to have_link(new_unfollow_dossier.id.to_s)
|
||||
end
|
||||
|
||||
scenario "should be able to find by region with custom enum lookup", js: true, vcr: { cassette_name: 'api_geo_regions' } do
|
||||
region_champ = new_unfollow_dossier.champs.find(&:region?)
|
||||
region_champ.update!(value: 'Bretagne', external_id: '53')
|
||||
region_champ.reload
|
||||
|
||||
click_on 'Sélectionner un filtre'
|
||||
select region_champ.libelle, from: "Colonne"
|
||||
find("select#value", visible: true)
|
||||
select region_champ.value, from: "Valeur"
|
||||
click_button "Ajouter le filtre"
|
||||
find("select#value", visible: false) # w8 for filter to be applied
|
||||
expect(page).to have_link(new_unfollow_dossier.id.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
scenario "should be able to add and remove two filters for the same field", js: true do
|
||||
add_filter(type_de_champ.libelle, champ.value)
|
||||
add_filter(type_de_champ.libelle, champ_2.value)
|
||||
|
|
|
@ -5,7 +5,7 @@ describe 'As an integrator:', js: true do
|
|||
before { visit "/preremplir/#{procedure.path}" }
|
||||
|
||||
scenario 'I can read the procedure prefilling (aka public champs)' do
|
||||
expect(page).to have_content(type_de_champ.to_typed_id)
|
||||
expect(page).to have_content(type_de_champ.to_typed_id_for_query)
|
||||
expect(page).to have_content(I18n.t("activerecord.attributes.type_de_champ.type_champs.#{type_de_champ.type_champ}"))
|
||||
expect(page).to have_content(type_de_champ.libelle)
|
||||
expect(page).to have_content(type_de_champ.description)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
describe 'Prefilling a dossier (with a GET request):' do
|
||||
describe 'Prefilling a dossier (with a GET request):', js: true do
|
||||
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
|
||||
|
||||
let(:password) { 'my-s3cure-p4ssword' }
|
||||
|
||||
let(:procedure) { create(:procedure, :published, opendata: true) }
|
||||
|
@ -6,10 +8,82 @@ describe 'Prefilling a dossier (with a GET request):' do
|
|||
|
||||
let(:type_de_champ_text) { create(:type_de_champ_text, procedure: procedure) }
|
||||
let(:type_de_champ_phone) { create(:type_de_champ_phone, procedure: procedure) }
|
||||
let(:type_de_champ_rna) { create(:type_de_champ_rna, procedure: procedure) }
|
||||
let(:type_de_champ_siret) { create(:type_de_champ_siret, procedure: procedure) }
|
||||
let(:type_de_champ_datetime) { create(:type_de_champ_datetime, procedure: procedure) }
|
||||
let(:type_de_champ_multiple_drop_down_list) { create(:type_de_champ_multiple_drop_down_list, procedure: procedure) }
|
||||
let(:type_de_champ_epci) { create(:type_de_champ_epci, procedure: procedure) }
|
||||
let(:type_de_champ_annuaire_education) { create(:type_de_champ_annuaire_education, procedure: procedure) }
|
||||
let(:type_de_champ_dossier_link) { create(:type_de_champ_dossier_link, procedure: procedure) }
|
||||
let(:type_de_champ_commune) { create(:type_de_champ_communes, procedure: procedure) }
|
||||
let(:type_de_champ_repetition) { create(:type_de_champ_repetition, :with_types_de_champ, procedure: procedure) }
|
||||
|
||||
let(:text_value) { "My Neighbor Totoro is the best movie ever" }
|
||||
let(:phone_value) { "invalid phone value" }
|
||||
let(:rna_value) { 'W595001988' }
|
||||
let(:siret_value) { '41816609600051' }
|
||||
let(:datetime_value) { "2023-02-01T10:32" }
|
||||
let(:multiple_drop_down_list_values) {
|
||||
[
|
||||
type_de_champ_multiple_drop_down_list.drop_down_list_enabled_non_empty_options.first,
|
||||
type_de_champ_multiple_drop_down_list.drop_down_list_enabled_non_empty_options.last
|
||||
]
|
||||
}
|
||||
let(:epci_value) { ['01', '200029999'] }
|
||||
let(:dossier_link_value) { '42' }
|
||||
let(:commune_value) { ['01', '01457'] } # Vonnas (01540)
|
||||
let(:sub_type_de_champs_repetition) { procedure.active_revision.children_of(type_de_champ_repetition) }
|
||||
let(:text_repetition_libelle) { sub_type_de_champs_repetition.first.libelle }
|
||||
let(:integer_repetition_libelle) { sub_type_de_champs_repetition.second.libelle }
|
||||
let(:text_repetition_value) { "First repetition text" }
|
||||
let(:integer_repetition_value) { "42" }
|
||||
let(:annuaire_education_value) { '0050009H' }
|
||||
|
||||
let(:entry_path) {
|
||||
commencer_path(
|
||||
path: procedure.path,
|
||||
"champ_#{type_de_champ_text.to_typed_id_for_query}" => text_value,
|
||||
"champ_#{type_de_champ_phone.to_typed_id_for_query}" => phone_value,
|
||||
"champ_#{type_de_champ_datetime.to_typed_id_for_query}" => datetime_value,
|
||||
"champ_#{type_de_champ_multiple_drop_down_list.to_typed_id_for_query}" => multiple_drop_down_list_values,
|
||||
"champ_#{type_de_champ_epci.to_typed_id_for_query}" => epci_value,
|
||||
"champ_#{type_de_champ_dossier_link.to_typed_id_for_query}" => dossier_link_value,
|
||||
"champ_#{type_de_champ_commune.to_typed_id_for_query}" => commune_value,
|
||||
"champ_#{type_de_champ_siret.to_typed_id_for_query}" => siret_value,
|
||||
"champ_#{type_de_champ_rna.to_typed_id_for_query}" => rna_value,
|
||||
"champ_#{type_de_champ_repetition.to_typed_id_for_query}" => [
|
||||
{
|
||||
"champ_#{sub_type_de_champs_repetition.first.to_typed_id_for_query}": text_repetition_value,
|
||||
"champ_#{sub_type_de_champs_repetition.second.to_typed_id_for_query}": integer_repetition_value
|
||||
}
|
||||
],
|
||||
"champ_#{type_de_champ_annuaire_education.to_typed_id_for_query}" => annuaire_education_value
|
||||
)
|
||||
}
|
||||
|
||||
before do
|
||||
allow(Rails).to receive(:cache).and_return(memory_store)
|
||||
Rails.cache.clear
|
||||
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\//)
|
||||
.to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/etablissements.json'))
|
||||
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siret_value[0..8]}/)
|
||||
.to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/entreprises.json'))
|
||||
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/associations\//)
|
||||
.to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/associations.json'))
|
||||
|
||||
VCR.insert_cassette('api_geo_departements')
|
||||
VCR.insert_cassette('api_geo_communes')
|
||||
VCR.insert_cassette('api_geo_epcis')
|
||||
end
|
||||
|
||||
after do
|
||||
VCR.eject_cassette('api_geo_departements')
|
||||
VCR.eject_cassette('api_geo_communes')
|
||||
VCR.eject_cassette('api_geo_epcis')
|
||||
end
|
||||
|
||||
context 'when authenticated' do
|
||||
it_behaves_like "the user has got a prefilled dossier, owned by themselves" do
|
||||
|
@ -18,13 +92,7 @@ describe 'Prefilling a dossier (with a GET request):' do
|
|||
before do
|
||||
visit "/users/sign_in"
|
||||
sign_in_with user.email, password
|
||||
|
||||
visit commencer_path(
|
||||
path: procedure.path,
|
||||
"champ_#{type_de_champ_text.to_typed_id}" => text_value,
|
||||
"champ_#{type_de_champ_phone.to_typed_id}" => phone_value,
|
||||
"champ_#{type_de_champ_datetime.to_typed_id}" => datetime_value
|
||||
)
|
||||
visit entry_path
|
||||
|
||||
click_on "Poursuivre mon dossier prérempli"
|
||||
end
|
||||
|
@ -65,14 +133,7 @@ describe 'Prefilling a dossier (with a GET request):' do
|
|||
end
|
||||
|
||||
context 'when unauthenticated' do
|
||||
before do
|
||||
visit commencer_path(
|
||||
path: procedure.path,
|
||||
"champ_#{type_de_champ_text.to_typed_id}" => text_value,
|
||||
"champ_#{type_de_champ_phone.to_typed_id}" => phone_value,
|
||||
"champ_#{type_de_champ_datetime.to_typed_id}" => datetime_value
|
||||
)
|
||||
end
|
||||
before { visit entry_path }
|
||||
|
||||
context 'when the user signs in with email and password' do
|
||||
it_behaves_like "the user has got a prefilled dossier, owned by themselves" do
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
describe 'Prefilling a dossier (with a POST request):' do
|
||||
describe 'Prefilling a dossier (with a POST request):', js: true do
|
||||
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
|
||||
|
||||
let(:password) { 'my-s3cure-p4ssword' }
|
||||
|
||||
let(:procedure) { create(:procedure, :published) }
|
||||
|
@ -6,10 +8,60 @@ describe 'Prefilling a dossier (with a POST request):' do
|
|||
|
||||
let(:type_de_champ_text) { create(:type_de_champ_text, procedure: procedure) }
|
||||
let(:type_de_champ_phone) { create(:type_de_champ_phone, procedure: procedure) }
|
||||
let(:type_de_champ_rna) { create(:type_de_champ_rna, procedure: procedure) }
|
||||
let(:type_de_champ_siret) { create(:type_de_champ_siret, procedure: procedure) }
|
||||
let(:type_de_champ_datetime) { create(:type_de_champ_datetime, procedure: procedure) }
|
||||
let(:type_de_champ_multiple_drop_down_list) { create(:type_de_champ_multiple_drop_down_list, procedure: procedure) }
|
||||
let(:type_de_champ_epci) { create(:type_de_champ_epci, procedure: procedure) }
|
||||
let(:type_de_champ_annuaire_education) { create(:type_de_champ_annuaire_education, procedure: procedure) }
|
||||
let(:type_de_champ_dossier_link) { create(:type_de_champ_dossier_link, procedure: procedure) }
|
||||
let(:type_de_champ_repetition) { create(:type_de_champ_repetition, :with_types_de_champ, procedure: procedure) }
|
||||
let(:type_de_champ_commune) { create(:type_de_champ_communes, procedure: procedure) }
|
||||
|
||||
let(:text_value) { "My Neighbor Totoro is the best movie ever" }
|
||||
let(:phone_value) { "invalid phone value" }
|
||||
let(:rna_value) { 'W595001988' }
|
||||
let(:siret_value) { '41816609600051' }
|
||||
let(:datetime_value) { "2023-02-01T10:32" }
|
||||
let(:multiple_drop_down_list_values) {
|
||||
[
|
||||
type_de_champ_multiple_drop_down_list.drop_down_list_enabled_non_empty_options.first,
|
||||
type_de_champ_multiple_drop_down_list.drop_down_list_enabled_non_empty_options.last
|
||||
]
|
||||
}
|
||||
let(:epci_value) { ['01', '200029999'] }
|
||||
let(:commune_value) { ['01', '01457'] } # Vonnas (01540)
|
||||
let(:sub_type_de_champs_repetition) { procedure.active_revision.children_of(type_de_champ_repetition) }
|
||||
let(:text_repetition_libelle) { sub_type_de_champs_repetition.first.libelle }
|
||||
let(:integer_repetition_libelle) { sub_type_de_champs_repetition.second.libelle }
|
||||
let(:text_repetition_value) { "First repetition text" }
|
||||
let(:integer_repetition_value) { "42" }
|
||||
let(:dossier_link_value) { '42' }
|
||||
let(:annuaire_education_value) { '0050009H' }
|
||||
|
||||
before do
|
||||
allow(Rails).to receive(:cache).and_return(memory_store)
|
||||
Rails.cache.clear
|
||||
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret_value}/)
|
||||
.to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/etablissements.json'))
|
||||
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siret_value[0..8]}/)
|
||||
.to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/entreprises.json'))
|
||||
|
||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/associations\//)
|
||||
.to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/associations.json'))
|
||||
|
||||
VCR.insert_cassette('api_geo_departements')
|
||||
VCR.insert_cassette('api_geo_communes')
|
||||
VCR.insert_cassette('api_geo_epcis')
|
||||
end
|
||||
|
||||
after do
|
||||
VCR.eject_cassette('api_geo_departements')
|
||||
VCR.eject_cassette('api_geo_communes')
|
||||
VCR.eject_cassette('api_geo_epcis')
|
||||
end
|
||||
|
||||
scenario "the user get the URL of a prefilled orphan brouillon dossier" do
|
||||
dossier_url = create_and_prefill_dossier_with_post_request
|
||||
|
@ -96,9 +148,22 @@ describe 'Prefilling a dossier (with a POST request):' do
|
|||
session.post api_public_v1_dossiers_path(procedure),
|
||||
headers: { "Content-Type" => "application/json" },
|
||||
params: {
|
||||
"champ_#{type_de_champ_text.to_typed_id}" => text_value,
|
||||
"champ_#{type_de_champ_phone.to_typed_id}" => phone_value,
|
||||
"champ_#{type_de_champ_datetime.to_typed_id}" => datetime_value
|
||||
"champ_#{type_de_champ_text.to_typed_id_for_query}" => text_value,
|
||||
"champ_#{type_de_champ_phone.to_typed_id_for_query}" => phone_value,
|
||||
"champ_#{type_de_champ_rna.to_typed_id_for_query}" => rna_value,
|
||||
"champ_#{type_de_champ_siret.to_typed_id_for_query}" => siret_value,
|
||||
"champ_#{type_de_champ_repetition.to_typed_id_for_query}" => [
|
||||
{
|
||||
"champ_#{sub_type_de_champs_repetition.first.to_typed_id_for_query}": text_repetition_value,
|
||||
"champ_#{sub_type_de_champs_repetition.second.to_typed_id_for_query}": integer_repetition_value
|
||||
}
|
||||
],
|
||||
"champ_#{type_de_champ_datetime.to_typed_id_for_query}" => datetime_value,
|
||||
"champ_#{type_de_champ_multiple_drop_down_list.to_typed_id_for_query}" => multiple_drop_down_list_values,
|
||||
"champ_#{type_de_champ_epci.to_typed_id_for_query}" => epci_value,
|
||||
"champ_#{type_de_champ_dossier_link.to_typed_id_for_query}" => dossier_link_value,
|
||||
"champ_#{type_de_champ_commune.to_typed_id_for_query}" => commune_value,
|
||||
"champ_#{type_de_champ_annuaire_education.to_typed_id_for_query}" => annuaire_education_value
|
||||
}.to_json
|
||||
JSON.parse(session.response.body)["dossier_url"].gsub("http://www.example.com", "")
|
||||
end
|
||||
|
|
|
@ -14,14 +14,14 @@ describe 'instructeurs/dossiers/envoyer_dossier_block.html.haml', type: :view do
|
|||
let(:potential_recipients) { [instructeur] }
|
||||
|
||||
it { is_expected.to match(/data-react-props.*#{instructeur.email}/) }
|
||||
it { is_expected.to have_css(".button.send") }
|
||||
it { is_expected.to have_css(".fr-btn") }
|
||||
end
|
||||
|
||||
context "there is no other instructeur for the procedure" do
|
||||
let(:potential_recipients) { [] }
|
||||
|
||||
it { is_expected.not_to have_css("select") }
|
||||
it { is_expected.not_to have_css(".button.send") }
|
||||
it { is_expected.not_to have_css(".fr-btn") }
|
||||
it { is_expected.to have_content("Vous êtes le seul instructeur assigné sur cette démarche") }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,7 +26,9 @@ describe 'instructeurs/shared/avis/_list.html.haml', type: :view do
|
|||
let(:avis) { [create(:avis, :with_answer, claimant: instructeur, experts_procedure: experts_procedure)] }
|
||||
|
||||
it 'renders the answer formatted with newlines' do
|
||||
expect(subject).to include(simple_format(avis.first.answer))
|
||||
expect(subject).to have_selector(".answer-body p", text: avis.first.answer.split("\n").first)
|
||||
expect(subject).to have_selector(".answer-body ul", count: 1) # avis.answer has two list item
|
||||
expect(subject).to have_selector(".answer-body ul li", count: 2)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue