[Fix #2258] Validate options for linked dropdown menus
This commit is contained in:
parent
b521095010
commit
998754ab73
4 changed files with 82 additions and 6 deletions
|
@ -3,6 +3,8 @@ class TypesDeChamp::LinkedDropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBas
|
|||
|
||||
delegate :drop_down_list, to: :@type_de_champ
|
||||
|
||||
validate :check_presence_of_primary_options
|
||||
|
||||
def primary_options
|
||||
primary_options = unpack_options.map(&:first)
|
||||
if primary_options.present?
|
||||
|
@ -21,6 +23,12 @@ class TypesDeChamp::LinkedDropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBas
|
|||
|
||||
private
|
||||
|
||||
def check_presence_of_primary_options
|
||||
if !PRIMARY_PATTERN.match?(drop_down_list.options.second)
|
||||
errors.add(libelle, "doit commencer par une entrée de menu primaire de la forme <code style='white-space: pre-wrap;'>--texte--</code>")
|
||||
end
|
||||
end
|
||||
|
||||
def unpack_options
|
||||
_, *options = drop_down_list.options
|
||||
chunked = options.slice_before(PRIMARY_PATTERN)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
class TypesDeChamp::TypeDeChampBase
|
||||
include ActiveModel::Validations
|
||||
|
||||
delegate :libelle, to: :@type_de_champ
|
||||
|
||||
def initialize(type_de_champ)
|
||||
@type_de_champ = type_de_champ
|
||||
end
|
||||
|
|
|
@ -54,7 +54,7 @@ FactoryBot.define do
|
|||
end
|
||||
factory :type_de_champ_linked_drop_down_list do
|
||||
type_champ { TypeDeChamp.type_champs.fetch(:linked_drop_down_list) }
|
||||
drop_down_list { create(:drop_down_list) }
|
||||
drop_down_list { create(:drop_down_list, value: "--primary--\nsecondary\n") }
|
||||
end
|
||||
factory :type_de_champ_pays do
|
||||
type_champ { TypeDeChamp.type_champs.fetch(:pays) }
|
||||
|
|
|
@ -1,12 +1,78 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe TypesDeChamp::LinkedDropDownListTypeDeChamp do
|
||||
describe '#unpack_options' do
|
||||
let(:drop_down_list) { build(:drop_down_list, value: menu_options) }
|
||||
let(:type_de_champ) { build(:type_de_champ_linked_drop_down_list, drop_down_list: drop_down_list) }
|
||||
|
||||
subject { type_de_champ.dynamic_type }
|
||||
|
||||
describe 'validation' do
|
||||
context 'It must start with one primary option' do
|
||||
context 'valid menu' do
|
||||
let(:menu_options) do
|
||||
<<~END_OPTIONS
|
||||
--Primary 1--
|
||||
secondary 1.1
|
||||
secondary 1.2
|
||||
--Primary 2--
|
||||
secondary 2.1
|
||||
secondary 2.2
|
||||
secondary 2.3
|
||||
END_OPTIONS
|
||||
end
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'degenerate but valid menu' do
|
||||
let(:menu_options) do
|
||||
<<~END_OPTIONS
|
||||
--Primary 1--
|
||||
END_OPTIONS
|
||||
end
|
||||
|
||||
it { is_expected.to be_valid }
|
||||
end
|
||||
|
||||
context 'invalid menus' do
|
||||
shared_examples 'missing primary option' do
|
||||
it { is_expected.to be_invalid }
|
||||
it do
|
||||
subject.validate
|
||||
expect(subject.errors.full_messages).to eq ["#{subject.libelle} doit commencer par une entrée de menu primaire de la forme <code style='white-space: pre-wrap;'>--texte--</code>"]
|
||||
end
|
||||
end
|
||||
|
||||
context 'no primary option' do
|
||||
let(:menu_options) do
|
||||
<<~END_OPTIONS
|
||||
secondary 1.1
|
||||
secondary 1.2
|
||||
END_OPTIONS
|
||||
end
|
||||
|
||||
it_should_behave_like 'missing primary option'
|
||||
end
|
||||
|
||||
context 'starting with secondary options' do
|
||||
let(:menu_options) do
|
||||
<<~END_OPTIONS
|
||||
secondary 1.1
|
||||
secondary 1.2
|
||||
--Primary 2--
|
||||
secondary 2.1
|
||||
secondary 2.2
|
||||
secondary 2.3
|
||||
END_OPTIONS
|
||||
end
|
||||
|
||||
it_should_behave_like 'missing primary option'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#unpack_options' do
|
||||
context 'with no options' do
|
||||
let(:menu_options) { '' }
|
||||
it { expect(subject.secondary_options).to eq({}) }
|
||||
|
|
Loading…
Reference in a new issue