0800bf68d0
Currently, deselecting all values from a multiple dropdown rendered as checkboxes doesn't have any effect when submitting the form (the previous values are still there, instead of being deselected). This is because unchecked checkboxes are not sent by the browser – so the "empty selection" never gets sent. Rails `form.check_box` usually works around this by inserting an empty hidden checkbox element, that will be sent even if all others are de-selected. But the documentation warns that this is not possible when iterating over an array (rather than a model). Which is our case here. To fix this, this commit uses `collection_check_boxes` instead. It will insert the proper hidden checkboxes in all cases, and fix our use case. See https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_check_boxes
104 lines
4.3 KiB
Ruby
104 lines
4.3 KiB
Ruby
describe 'shared/dossiers/edit.html.haml', type: :view do
|
|
before do
|
|
allow(controller).to receive(:current_user).and_return(dossier.user)
|
|
end
|
|
|
|
subject { render 'shared/dossiers/edit.html.haml', dossier: dossier, apercu: false }
|
|
|
|
context 'when there are some champs' do
|
|
let(:dossier) { create(:dossier) }
|
|
let(:champ_checkbox) { create(:champ_checkbox, dossier: dossier, value: 'on') }
|
|
let(:champ_header_section) { create(:champ_header_section, dossier: dossier, value: 'Section') }
|
|
let(:champ_explication) { create(:champ_explication, dossier: dossier, value: 'mazette') }
|
|
let(:champ_dossier_link) { create(:champ_dossier_link, dossier: dossier, value: dossier.id) }
|
|
let(:champ_textarea) { create(:champ_textarea, dossier: dossier, value: 'Some long text in a textarea.') }
|
|
let(:champs) { [champ_checkbox, champ_header_section, champ_explication, champ_dossier_link, champ_textarea] }
|
|
|
|
before { dossier.champs << champs }
|
|
|
|
it 'renders labels and editable values of champs' do
|
|
expect(subject).to have_field(champ_checkbox.libelle, checked: true)
|
|
expect(subject).to have_css(".header-section", text: champ_header_section.libelle)
|
|
expect(subject).to have_text(champ_explication.libelle)
|
|
expect(subject).to have_field(champ_dossier_link.libelle, with: champ_dossier_link.value)
|
|
expect(subject).to have_field(champ_textarea.libelle, with: champ_textarea.value)
|
|
end
|
|
end
|
|
|
|
context 'with a single-value list' do
|
|
let(:dossier) { create(:dossier) }
|
|
let(:type_de_champ) { create(:type_de_champ_drop_down_list, mandatory: mandatory, procedure: dossier.procedure) }
|
|
let(:champ) { create(:champ_drop_down_list, dossier: dossier, type_de_champ: type_de_champ) }
|
|
let(:options) { type_de_champ.drop_down_list_options }
|
|
let(:enabled_options) { type_de_champ.drop_down_list_enabled_non_empty_options }
|
|
let(:mandatory) { true }
|
|
|
|
before { dossier.champs << champ }
|
|
|
|
context 'when the list is short' do
|
|
it 'renders the list as radio buttons' do
|
|
expect(subject).to have_selector('input[type=radio]', count: enabled_options.count)
|
|
end
|
|
|
|
context 'when the champ is optional' do
|
|
let(:mandatory) { false }
|
|
|
|
it 'allows unselecting a previously selected value' do
|
|
expect(subject).to have_selector('input[type=radio]', count: enabled_options.count + 1)
|
|
expect(subject).to have_unchecked_field('Non renseigné', count: 1)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when the list is long' do
|
|
let(:type_de_champ) { create(:type_de_champ_drop_down_list, :long, procedure: dossier.procedure) }
|
|
|
|
it 'renders the list as a dropdown' do
|
|
expect(subject).to have_select(type_de_champ.libelle, options: options)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'with a multiple-values list' do
|
|
let(:dossier) { create(:dossier) }
|
|
let(:type_de_champ) { create(:type_de_champ_multiple_drop_down_list, procedure: dossier.procedure) }
|
|
let(:champ) { create(:champ_multiple_drop_down_list, dossier: dossier, type_de_champ: type_de_champ) }
|
|
let(:options) { type_de_champ.drop_down_list_options }
|
|
let(:enabled_options) { type_de_champ.drop_down_list_enabled_non_empty_options }
|
|
|
|
before { dossier.champs << champ }
|
|
|
|
context 'when the list is short' do
|
|
it 'renders the list as checkboxes' do
|
|
expect(subject).to have_selector('input[type=checkbox]', count: enabled_options.count)
|
|
end
|
|
|
|
it 'adds an extra hidden input, to send a blank value even when all checkboxes are unchecked' do
|
|
expect(subject).to have_selector('input[type=hidden][value=""]')
|
|
end
|
|
end
|
|
|
|
context 'when the list is long' do
|
|
let(:type_de_champ) { create(:type_de_champ_multiple_drop_down_list, :long, procedure: dossier.procedure) }
|
|
|
|
it 'renders the list as a multiple-selection dropdown' do
|
|
expect(subject).to have_selector('select.select2')
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'with a routed procedure' do
|
|
let(:procedure) do
|
|
create(:procedure,
|
|
:routee,
|
|
routing_criteria_name: 'departement')
|
|
end
|
|
let(:dossier) { create(:dossier, procedure: procedure) }
|
|
let(:champs) { [] }
|
|
|
|
it 'renders the routing criteria name and its value' do
|
|
expect(subject).to have_field(procedure.routing_criteria_name)
|
|
expect(subject).to include(dossier.groupe_instructeur.label)
|
|
end
|
|
end
|
|
end
|