Merge pull request #8479 from demarches-simplifiees/prefill/multiple
prefill(dossier): prefill multiple drop down list champ
This commit is contained in:
commit
8aece28f75
18 changed files with 152 additions and 28 deletions
|
@ -23,6 +23,8 @@
|
|||
class Champs::MultipleDropDownListChamp < Champ
|
||||
before_save :format_before_save
|
||||
|
||||
validate :values_are_in_options, if: -> { value.present? }
|
||||
|
||||
def options?
|
||||
drop_down_list_options?
|
||||
end
|
||||
|
@ -90,4 +92,12 @@ class Champs::MultipleDropDownListChamp < Champ
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def values_are_in_options
|
||||
json = selected_options.reject(&:blank?)
|
||||
return if json.empty?
|
||||
return if (json - enabled_non_empty_options).empty?
|
||||
|
||||
errors.add(:value, :not_in_options)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,6 +42,7 @@ class PrefillParams
|
|||
TypeDeChamp.type_champs.fetch(:pays),
|
||||
TypeDeChamp.type_champs.fetch(:regions),
|
||||
TypeDeChamp.type_champs.fetch(:departements),
|
||||
TypeDeChamp.type_champs.fetch(:multiple_drop_down_list),
|
||||
TypeDeChamp.type_champs.fetch(:epci)
|
||||
]
|
||||
|
||||
|
|
|
@ -262,13 +262,14 @@ class TypeDeChamp < ApplicationRecord
|
|||
TypeDeChamp.type_champs.fetch(:iban),
|
||||
TypeDeChamp.type_champs.fetch(:civilite),
|
||||
TypeDeChamp.type_champs.fetch(:pays),
|
||||
TypeDeChamp.type_champs.fetch(:regions),
|
||||
TypeDeChamp.type_champs.fetch(:date),
|
||||
TypeDeChamp.type_champs.fetch(:datetime),
|
||||
TypeDeChamp.type_champs.fetch(:yes_no),
|
||||
TypeDeChamp.type_champs.fetch(:checkbox),
|
||||
TypeDeChamp.type_champs.fetch(:drop_down_list),
|
||||
TypeDeChamp.type_champs.fetch(:regions),
|
||||
TypeDeChamp.type_champs.fetch(:departements),
|
||||
TypeDeChamp.type_champs.fetch(:multiple_drop_down_list),
|
||||
TypeDeChamp.type_champs.fetch(:epci)
|
||||
])
|
||||
end
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
class TypesDeChamp::PrefillMultipleDropDownListTypeDeChamp < TypesDeChamp::PrefillDropDownListTypeDeChamp
|
||||
def example_value
|
||||
return nil if possible_values.empty?
|
||||
return possible_values.first if possible_values.one?
|
||||
|
||||
[possible_values.first, possible_values.second]
|
||||
end
|
||||
end
|
|
@ -5,6 +5,8 @@ class TypesDeChamp::PrefillTypeDeChamp < SimpleDelegator
|
|||
case type_de_champ.type_champ
|
||||
when TypeDeChamp.type_champs.fetch(:drop_down_list)
|
||||
TypesDeChamp::PrefillDropDownListTypeDeChamp.new(type_de_champ)
|
||||
when TypeDeChamp.type_champs.fetch(:multiple_drop_down_list)
|
||||
TypesDeChamp::PrefillMultipleDropDownListTypeDeChamp.new(type_de_champ)
|
||||
when TypeDeChamp.type_champs.fetch(:pays)
|
||||
TypesDeChamp::PrefillPaysTypeDeChamp.new(type_de_champ)
|
||||
when TypeDeChamp.type_champs.fetch(:regions)
|
||||
|
|
|
@ -471,6 +471,10 @@ en:
|
|||
attributes:
|
||||
value:
|
||||
not_in_options: "must be in the given options"
|
||||
"champs/multiple_drop_down_list_champ":
|
||||
attributes:
|
||||
value:
|
||||
not_in_options: "must be in the given options"
|
||||
"champs/region_champ":
|
||||
attributes:
|
||||
value:
|
||||
|
|
|
@ -466,6 +466,10 @@ fr:
|
|||
attributes:
|
||||
value:
|
||||
not_in_options: "doit être dans les options proposées"
|
||||
"champs/multiple_drop_down_list_champ":
|
||||
attributes:
|
||||
value:
|
||||
not_in_options: "doit être dans les options proposées"
|
||||
"champs/region_champ":
|
||||
attributes:
|
||||
value:
|
||||
|
|
|
@ -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']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
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
|
|
@ -128,6 +128,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"
|
||||
|
@ -135,8 +136,8 @@ 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", :multiple_drop_down_list, ["val1", "val2"]
|
||||
it_behaves_like "a champ public value that is authorized", :epci, ['01', '200042935']
|
||||
|
||||
it_behaves_like "a champ private value that is authorized", :text, "value"
|
||||
|
@ -148,6 +149,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"
|
||||
|
@ -157,6 +159,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", :multiple_drop_down_list, ["val1", "val2"]
|
||||
it_behaves_like "a champ private value that is authorized", :epci, ['01', '200042935']
|
||||
|
||||
it_behaves_like "a champ public value that is unauthorized", :decimal_number, "non decimal string"
|
||||
|
@ -169,7 +172,6 @@ RSpec.describe PrefillParams do
|
|||
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"
|
||||
|
@ -187,6 +189,7 @@ RSpec.describe PrefillParams do
|
|||
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", :multiple_drop_down_list, ["value"]
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -246,18 +246,18 @@ 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_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_departements
|
||||
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 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
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe TypesDeChamp::PrefillMultipleDropDownListTypeDeChamp do
|
||||
describe 'ancestors' do
|
||||
subject { described_class.new(build(:type_de_champ_multiple_drop_down_list)) }
|
||||
|
||||
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) }
|
||||
subject(:example_value) { described_class.new(type_de_champ).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
|
|
@ -10,6 +10,12 @@ RSpec.describe TypesDeChamp::PrefillTypeDeChamp, type: :model do
|
|||
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) }
|
||||
|
||||
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) }
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@ shared_examples "the user has got a prefilled dossier, owned by themselves" do
|
|||
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_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)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,12 +9,30 @@ 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_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(:text_value) { "My Neighbor Totoro is the best movie ever" }
|
||||
let(:phone_value) { "invalid phone value" }
|
||||
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(:entry_path) {
|
||||
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,
|
||||
"champ_#{type_de_champ_multiple_drop_down_list.to_typed_id}" => multiple_drop_down_list_values,
|
||||
"champ_#{type_de_champ_epci.to_typed_id}" => epci_value
|
||||
)
|
||||
}
|
||||
|
||||
before do
|
||||
allow(Rails).to receive(:cache).and_return(memory_store)
|
||||
Rails.cache.clear
|
||||
|
@ -36,13 +54,7 @@ describe 'Prefilling a dossier (with a GET request):' 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,
|
||||
"champ_#{type_de_champ_epci.to_typed_id}" => epci_value
|
||||
)
|
||||
visit entry_path
|
||||
|
||||
click_on "Poursuivre mon dossier prérempli"
|
||||
end
|
||||
|
@ -50,15 +62,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,
|
||||
"champ_#{type_de_champ_epci.to_typed_id}" => epci_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
|
||||
|
|
|
@ -9,10 +9,17 @@ 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_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(:text_value) { "My Neighbor Totoro is the best movie ever" }
|
||||
let(:phone_value) { "invalid phone value" }
|
||||
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'] }
|
||||
|
||||
before do
|
||||
|
@ -116,6 +123,7 @@ describe 'Prefilling a dossier (with a POST request):' do
|
|||
"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_multiple_drop_down_list.to_typed_id}" => multiple_drop_down_list_values,
|
||||
"champ_#{type_de_champ_epci.to_typed_id}" => epci_value
|
||||
}.to_json
|
||||
JSON.parse(session.response.body)["dossier_url"].gsub("http://www.example.com", "")
|
||||
|
|
Loading…
Add table
Reference in a new issue