diff --git a/app/models/types_de_champ/prefill_commune_type_de_champ.rb b/app/models/types_de_champ/prefill_commune_type_de_champ.rb new file mode 100644 index 000000000..38335498a --- /dev/null +++ b/app/models/types_de_champ/prefill_commune_type_de_champ.rb @@ -0,0 +1,33 @@ +class TypesDeChamp::PrefillCommuneTypeDeChamp < TypesDeChamp::PrefillTypeDeChamp + def transform_value_to_assignable_attributes(value) + return if value.blank? || !value.is_a?(Array) + return if (departement_code = value.first).blank? + return if (departement_name = APIGeoService.departement_name(departement_code)).blank? + return if !value.one? && (commune_code = value.second).blank? + return if !value.one? && (commune_name = APIGeoService.commune_name(departement_code, commune_code)).blank? + + if value.one? + departement_attributes(departement_code, departement_name) + else + departement_and_commune_attributes(departement_code, departement_name, commune_code, commune_name) + end + end + + private + + def departement_attributes(departement_code, departement_name) + { + code_departement: departement_code, + departement: departement_name + } + end + + def departement_and_commune_attributes(departement_code, departement_name, commune_code, commune_name) + postal_code = APIGeoService.commune_postal_codes(departement_code, commune_code).first + + departement_attributes(departement_code, departement_name).merge( + external_id: commune_code, + value: "#{commune_name} (#{postal_code})" + ) + end +end diff --git a/app/models/types_de_champ/prefill_type_de_champ.rb b/app/models/types_de_champ/prefill_type_de_champ.rb index 43bf2c493..34dee1206 100644 --- a/app/models/types_de_champ/prefill_type_de_champ.rb +++ b/app/models/types_de_champ/prefill_type_de_champ.rb @@ -23,6 +23,8 @@ class TypesDeChamp::PrefillTypeDeChamp < SimpleDelegator TypesDeChamp::PrefillRepetitionTypeDeChamp.new(type_de_champ, revision) when TypeDeChamp.type_champs.fetch(:departements) TypesDeChamp::PrefillDepartementTypeDeChamp.new(type_de_champ, revision) + when TypeDeChamp.type_champs.fetch(:communes) + TypesDeChamp::PrefillCommuneTypeDeChamp.new(type_de_champ, revision) when TypeDeChamp.type_champs.fetch(:epci) TypesDeChamp::PrefillEpciTypeDeChamp.new(type_de_champ, revision) else diff --git a/spec/models/prefill_params_spec.rb b/spec/models/prefill_params_spec.rb index 5eaa97071..3356cf448 100644 --- a/spec/models/prefill_params_spec.rb +++ b/spec/models/prefill_params_spec.rb @@ -15,12 +15,14 @@ RSpec.describe PrefillParams do 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 @@ -137,7 +139,7 @@ RSpec.describe PrefillParams do 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", :departements, "03" - it_behaves_like "a champ public value that is authorized", :communes, ['56', '56081'] + it_behaves_like "a champ public value that is authorized", :communes, ['01', '01457'] 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", :epci, ['01', '200042935'] @@ -174,7 +176,7 @@ RSpec.describe PrefillParams do 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", :departements, "03" - it_behaves_like "a champ private value that is authorized", :communes, ['56', '56081'] + it_behaves_like "a champ private value that is authorized", :communes, ['01', '01457'] 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", :epci, ['01', '200042935'] diff --git a/spec/models/types_de_champ/prefill_commune_type_de_champ_spec.rb b/spec/models/types_de_champ/prefill_commune_type_de_champ_spec.rb new file mode 100644 index 000000000..fb92b1a36 --- /dev/null +++ b/spec/models/types_de_champ/prefill_commune_type_de_champ_spec.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +RSpec.describe TypesDeChamp::PrefillCommuneTypeDeChamp do + let(:type_de_champ) { build(:type_de_champ_communes) } + 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) } + + it { is_expected.to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) } + end + + describe '#transform_value_to_assignable_attributes' do + subject(:transform_value_to_assignable_attributes) do + described_class.build(type_de_champ).transform_value_to_assignable_attributes(value) + 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 + + shared_examples "a transformation to" do |expected| + it { is_expected.to match(expected) } + end + + context 'when the value is nil' do + let(:value) { nil } + it_behaves_like "a transformation to", nil + end + + context 'when the value is empty' do + let(:value) { '' } + it_behaves_like "a transformation to", nil + end + + context 'when the value is a string' do + let(:value) { 'hello' } + it_behaves_like "a transformation to", 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_behaves_like "a transformation to", { code_departement: '01', departement: 'Ain' } + end + + context 'when the first element is not a valid departement code' do + let(:value) { ['totoro'] } + it_behaves_like "a transformation to", 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_behaves_like "a transformation to", { 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_behaves_like "a transformation to", nil + end + end + + context 'when the first element is not a valid departement code' do + let(:value) { ['totoro', '01457'] } + it_behaves_like "a transformation to", 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_behaves_like "a transformation to", { 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_behaves_like "a transformation to", nil + end + end + + context 'when the first element is not a valid departement code' do + let(:value) { ['totoro', '01457', 'hello'] } + it_behaves_like "a transformation to", nil + end + end + end +end diff --git a/spec/models/types_de_champ/prefill_type_de_champ_spec.rb b/spec/models/types_de_champ/prefill_type_de_champ_spec.rb index 1a6dc0c8a..844115889 100644 --- a/spec/models/types_de_champ/prefill_type_de_champ_spec.rb +++ b/spec/models/types_de_champ/prefill_type_de_champ_spec.rb @@ -45,6 +45,12 @@ RSpec.describe TypesDeChamp::PrefillTypeDeChamp, type: :model do 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) }