transform the input value to assignable attributes

Use the prefill decorator to transform the input value (for example
['01', '200042935']) into assignables attributes (for example
{ code_departement: '01', value: '200042935' }), in order to let the
champ be prefilled successfully.
This commit is contained in:
sebastiencarceles 2023-02-06 11:22:26 +01:00
parent 0f483668cf
commit f836f57e98
6 changed files with 110 additions and 11 deletions

View file

@ -56,10 +56,7 @@ class PrefillParams
end
def to_h
{
id: champ.id,
value: value
}
{ id: champ.id }.merge(champ_attributes)
end
private
@ -67,8 +64,14 @@ class PrefillParams
def valid?
return true unless NEED_VALIDATION_TYPES_DE_CHAMPS.include?(champ.type_champ)
champ.value = value
champ.assign_attributes(champ_attributes)
champ.valid?(:prefill)
end
def champ_attributes
TypesDeChamp::PrefillTypeDeChamp
.build(champ.type_de_champ)
.transform_value_to_assignable_attributes(value)
end
end
end

View file

@ -0,0 +1,23 @@
class TypesDeChamp::PrefillEpciTypeDeChamp < TypesDeChamp::PrefillTypeDeChamp
def possible_values
departements.map { |departement| "#{departement[:code]} (#{departement[:name]})" }
end
def example_value
departement_code = departements.pick(:code)
epci_code = APIGeoService.epcis(departement_code).pick(:code)
[departement_code, epci_code]
end
def transform_value_to_assignable_attributes(value)
return { code_departement: nil, value: nil } if value.blank? || !value.is_a?(Array)
return { code_departement: value.first, value: nil } if value.one?
{ code_departement: value.first, value: value.second }
end
private
def departements
@departements ||= APIGeoService.departements.sort_by { |departement| departement[:code] }
end
end

View file

@ -11,6 +11,8 @@ class TypesDeChamp::PrefillTypeDeChamp < SimpleDelegator
TypesDeChamp::PrefillRegionTypeDeChamp.new(type_de_champ)
when TypeDeChamp.type_champs.fetch(:departements)
TypesDeChamp::PrefillDepartementTypeDeChamp.new(type_de_champ)
when TypeDeChamp.type_champs.fetch(:epci)
TypesDeChamp::PrefillEpciTypeDeChamp.new(type_de_champ)
else
new(type_de_champ)
end
@ -33,4 +35,8 @@ class TypesDeChamp::PrefillTypeDeChamp < SimpleDelegator
def too_many_possible_values?
possible_values.count > POSSIBLE_VALUES_THRESHOLD
end
def transform_value_to_assignable_attributes(value)
{ value: value }
end
end

View file

@ -72,12 +72,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 } }
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 +86,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 } }
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
@ -184,4 +184,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)
.transform_value_to_assignable_attributes(value)
end
end

View file

@ -0,0 +1,47 @@
# frozen_string_literal: true
RSpec.describe TypesDeChamp::PrefillEpciTypeDeChamp do
let(:type_de_champ) { build(:type_de_champ_epci) }
describe 'ancestors' do
subject { described_class.new(type_de_champ) }
it { is_expected.to be_kind_of(TypesDeChamp::PrefillEpciTypeDeChamp) }
end
# TODO: SEB describe '#possible_values'
# TODO: SEB describe '#example_value'
describe '#transform_value_to_assignable_attributes' do
subject(:transform_value_to_assignable_attributes) { described_class.build(type_de_champ).transform_value_to_assignable_attributes(value) }
context 'when the value is nil' do
let(:value) { nil }
it { is_expected.to match({ code_departement: nil, value: nil }) }
end
context 'when the value is empty' do
let(:value) { '' }
it { is_expected.to match({ code_departement: nil, value: nil }) }
end
context 'when the value is a string' do
let(:value) { 'hello' }
it { is_expected.to match({ code_departement: nil, value: nil }) }
end
context 'when the value is an array of one element' do
let(:value) { ['01'] }
it { is_expected.to match({ code_departement: '01', value: nil }) }
end
context 'when the value is an array of two elements' do
let(:value) { ['01', '200042935'] }
it { is_expected.to match({ code_departement: '01', value: '200042935' }) }
end
context 'when the value is an array of three or more elements' do
let(:value) { ['01', '200042935', 'hello'] }
it { is_expected.to match({ code_departement: '01', value: '200042935' }) }
end
end
end

View file

@ -28,6 +28,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 epci' do
let(:type_de_champ) { build(:type_de_champ_epci) }
it { expect(built).to be_kind_of(TypesDeChamp::PrefillEpciTypeDeChamp) }
end
context 'when any other type de champ' do
let(:type_de_champ) { build(:type_de_champ_date) }
@ -92,4 +98,12 @@ RSpec.describe TypesDeChamp::PrefillTypeDeChamp, type: :model do
it { expect(too_many_possible_values).to eq(false) }
end
end
describe '#transform_value_to_assignable_attributes' do
let(:type_de_champ) { build(:type_de_champ_email) }
let(:value) { "any@email.org" }
subject(:transform_value_to_assignable_attributes) { described_class.build(type_de_champ).transform_value_to_assignable_attributes(value) }
it { is_expected.to match({ value: value }) }
end
end