spec(move_and_morph): add some spec and lint with rubocop/haml/eslint
This commit is contained in:
parent
857a1fc496
commit
e7eee7ba72
7 changed files with 112 additions and 34 deletions
|
@ -1,6 +1,6 @@
|
||||||
- c = TypesDeChampEditor::SelectChampTemplatePositionComponent.new(block: @block, coordinates: @coordinates)
|
- c = TypesDeChampEditor::SelectChampTemplatePositionComponent.new(block: @block, coordinates: @coordinates)
|
||||||
%ul.types-de-champ-block{ id: block_id, data: sortable_options.merge(controller: 'select-champ-position-template', 'select-champ-position-template-template-id-value': c.block_id ) }
|
%ul.types-de-champ-block{ id: block_id, data: sortable_options.merge(controller: 'select-champ-position-template', 'select-champ-position-template-template-id-value': c.block_id ) }
|
||||||
%li.hidden= render c
|
|
||||||
- @coordinates.each do |coordinate|
|
- @coordinates.each do |coordinate|
|
||||||
= render TypesDeChampEditor::ChampComponent.new(coordinate:, upper_coordinates: coordinate.upper_coordinates)
|
= render TypesDeChampEditor::ChampComponent.new(coordinate:, upper_coordinates: coordinate.upper_coordinates)
|
||||||
|
%li.hidden= render c
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,7 @@ class TypesDeChampEditor::ChampComponent < ApplicationComponent
|
||||||
controller: 'type-de-champ-editor',
|
controller: 'type-de-champ-editor',
|
||||||
type_de_champ_editor_move_url_value: move_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
type_de_champ_editor_move_url_value: move_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
||||||
type_de_champ_editor_move_up_url_value: move_up_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
type_de_champ_editor_move_up_url_value: move_up_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
||||||
type_de_champ_editor_move_down_url_value: move_down_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id),
|
type_de_champ_editor_move_down_url_value: move_down_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id)
|
||||||
type_de_champ_editor_move_and_morph_url_value: move_and_morph_admin_procedure_type_de_champ_path(procedure, type_de_champ.stable_id)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
= form_with(url: move_and_morph_admin_procedure_type_de_champ_path(@coordinate.revision.procedure, @coordinate.type_de_champ.stable_id), class: 'fr-ml-3w flex', method: :patch, data: { turbo: true }) do |f|
|
= form_with(url: move_and_morph_admin_procedure_type_de_champ_path(@coordinate.revision.procedure, @coordinate.type_de_champ.stable_id), class: 'fr-ml-3w flex', method: :patch, data: { turbo: true }) do |f|
|
||||||
= label_tag :target_stable_id, "Déplacer le champ", for: describedby_id, class: 'flex align-center flex-no-shrink fr-mr-3w'
|
= label_tag :target_stable_id, "Déplacer le champ", for: describedby_id, class: 'flex align-center flex-no-shrink fr-mr-3w'
|
||||||
= select_tag :target_stable_id, options_for_select(options), id: describedby_id, class: 'fr-select', aria: { discribedby: describedby_id }, data: { 'select-champ-position-template-target': 'select', selected: @coordinate.stable_id }
|
= select_tag :target_stable_id, options_for_select(options), id: describedby_id, class: 'fr-select', aria: { discribedby: describedby_id }, data: { 'select-champ-position-template-target': 'select', selected: @coordinate.stable_id }
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
%select
|
%select
|
||||||
%option{ disabled: :disabled } Selectionner une option
|
%option{ disabled: :disabled } Selectionner une option
|
||||||
- @coordinates.each do |coordinate|
|
- @coordinates.each do |coordinate|
|
||||||
%option{ value: coordinate.stable_id }= "#{coordinate.position} #{coordinate.libelle}"
|
%option{ value: coordinate.stable_id }= "#{coordinate.position} #{coordinate.libelle}"
|
||||||
|
|
|
@ -61,6 +61,7 @@ export class SelectChampPositionTemplateController extends ApplicationController
|
||||||
if (stableIdDidChange) {
|
if (stableIdDidChange) {
|
||||||
changedSelectTarget.form?.requestSubmit();
|
changedSelectTarget.form?.requestSubmit();
|
||||||
}
|
}
|
||||||
|
event.stopImmediatePropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
private getStableIdForSelect(select: HTMLSelectElement): string | null {
|
private getStableIdForSelect(select: HTMLSelectElement): string | null {
|
||||||
|
|
|
@ -65,7 +65,7 @@ describe TypesDeChampEditor::ChampComponent, type: :component do
|
||||||
let(:coordinate) { procedure.draft_revision.revision_types_de_champ_public.first }
|
let(:coordinate) { procedure.draft_revision.revision_types_de_champ_public.first }
|
||||||
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :text, libelle: 'a' }]) }
|
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :text, libelle: 'a' }]) }
|
||||||
it 'does not have select to move champs' do
|
it 'does not have select to move champs' do
|
||||||
expect(page).not_to have_css("select##{ActionView::RecordIdentifier.dom_id(coordinate, :move_and_morph)}")
|
expect(page).to have_css("select##{ActionView::RecordIdentifier.dom_id(coordinate, :move_and_morph)}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -234,37 +234,115 @@ describe 'As an administrateur I can edit types de champ', js: true do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'move and morph champs' do
|
context 'move and morph' do
|
||||||
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :text, libelle: 'first_tdc' }, { type: :text, libelle: 'middle_tdc' }, { type: :text, libelle: 'last_tdc' }]) }
|
let(:procedure) { create(:procedure, types_de_champ_public: tdcs) }
|
||||||
let!(:initial_first_coordinate) { procedure.draft_revision.revision_types_de_champ[0] }
|
let!(:initial_first_coordinate) { procedure.draft_revision.revision_types_de_champ_public[0] }
|
||||||
let!(:initial_second_coordinate) { procedure.draft_revision.revision_types_de_champ[1] }
|
let!(:initial_second_coordinate) { procedure.draft_revision.revision_types_de_champ_public[1] }
|
||||||
let!(:initial_third_coordinate) { procedure.draft_revision.revision_types_de_champ[2] }
|
let!(:initial_third_coordinate) { procedure.draft_revision.revision_types_de_champ_public[2] }
|
||||||
# TODO: check no select when 1 champs
|
|
||||||
# TODO: check empty select when 1 champs
|
|
||||||
# TODO: check select is seeding on focus
|
|
||||||
# TODO: check select.change move champ and keep order
|
|
||||||
# TODO: select options are segmented by block
|
|
||||||
scenario 'root champs' do
|
|
||||||
initial_order = [initial_first_coordinate, initial_second_coordinate, initial_third_coordinate].map(&:stable_id)
|
|
||||||
initial_first_coordinate_selector = "##{ActionView::RecordIdentifier.dom_id(initial_first_coordinate, :move_and_morph)}"
|
|
||||||
# at first, select only contains the current coordinate
|
|
||||||
expect(page).to have_selector("#{initial_first_coordinate_selector} option", count: 1)
|
|
||||||
expect(page.find(initial_first_coordinate_selector).all("option").first.value.to_s).to eq(initial_first_coordinate.stable_id.to_s)
|
|
||||||
|
|
||||||
# once clicked, the select is updated other options
|
context 'with root champs' do
|
||||||
page.find(initial_first_coordinate_selector).click
|
let(:tdcs) do
|
||||||
expect(page).to have_selector("#{initial_first_coordinate_selector} option", count: 4)
|
[
|
||||||
# also we re-hydrate the selected value
|
{ type: :text, libelle: 'first_tdc' },
|
||||||
expect(page.find(initial_first_coordinate_selector).find("option[selected]").value.to_s).to eq(initial_first_coordinate.stable_id.to_s)
|
{ type: :text, libelle: 'middle_tdc' },
|
||||||
page.find(initial_first_coordinate_selector).select(initial_third_coordinate.libelle)
|
{ type: :text, libelle: 'last_tdc' }
|
||||||
wait_until do
|
]
|
||||||
procedure.reload.draft_revision.revision_types_de_champ.last.type_de_champ.libelle == initial_first_coordinate.type_de_champ.libelle
|
end
|
||||||
|
let(:initial_first_coordinate_selector) { "##{ActionView::RecordIdentifier.dom_id(initial_first_coordinate, :move_and_morph)}" }
|
||||||
|
|
||||||
|
scenario 'root select is empty by default' do
|
||||||
|
# at first, select only contains the current coordinate
|
||||||
|
expect(page).to have_selector("#{initial_first_coordinate_selector} option", count: 1)
|
||||||
|
expect(page.find(initial_first_coordinate_selector).all("option").first.value.to_s).to eq(initial_first_coordinate.stable_id.to_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'when select is focused, it seeds its options' do
|
||||||
|
# once clicked, the select is updated with root champs options only, preselected on coordinates and have nice libelles
|
||||||
|
page.find(initial_first_coordinate_selector).click
|
||||||
|
expect(page).to have_selector("#{initial_first_coordinate_selector} option", count: 4)
|
||||||
|
expect(page.find(initial_first_coordinate_selector).find("option[selected]").value.to_s).to eq(initial_first_coordinate.stable_id.to_s)
|
||||||
|
expect(page.find(initial_first_coordinate_selector).all("option").map(&:text)).to match_array(["Selectionner une option", '0 first_tdc', '1 middle_tdc', '2 last_tdc'])
|
||||||
|
|
||||||
|
# renaming a tdc renames it's option
|
||||||
|
within "##{dom_id(initial_first_coordinate, :type_de_champ_editor)}" do
|
||||||
|
fill_in 'Libellé du champ', with: 'renamed'
|
||||||
|
end
|
||||||
|
wait_until { initial_first_coordinate.reload.libelle == 'renamed' }
|
||||||
|
page.find(initial_first_coordinate_selector).click
|
||||||
|
expect(page.find(initial_first_coordinate_selector).all("option").map(&:text)).to match_array(["Selectionner une option", '0 renamed', '1 middle_tdc', '2 last_tdc'])
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'when select is changed, it move the coordinates' do
|
||||||
|
page.find(initial_first_coordinate_selector).click # seeds
|
||||||
|
page.find(initial_first_coordinate_selector).select(initial_third_coordinate.libelle)
|
||||||
|
wait_until do
|
||||||
|
procedure.reload.draft_revision.revision_types_de_champ.last.type_de_champ.libelle == initial_first_coordinate.type_de_champ.libelle
|
||||||
|
end
|
||||||
|
# wait until turbo response
|
||||||
|
expect(page).to have_text('Formulaire enregistré')
|
||||||
|
|
||||||
|
# check reorder worked on backend
|
||||||
|
reordered_coordinates = [initial_second_coordinate, initial_third_coordinate, initial_first_coordinate]
|
||||||
|
expect(procedure.reload.draft_revision.revision_types_de_champ.map(&:stable_id)).to eq(reordered_coordinates.map(&:stable_id))
|
||||||
|
|
||||||
|
# check reorder rerendered champ component between target->destination
|
||||||
|
reordered_coordinates.map(&:reload).map do |coordinate|
|
||||||
|
expect(page).to have_selector("##{ActionView::RecordIdentifier.dom_id(coordinate, :type_de_champ_editor)} .position", text: "##{coordinate.position}")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
expect(procedure.reload.draft_revision.revision_types_de_champ.map(&:stable_id))
|
|
||||||
.to eq([initial_second_coordinate, initial_third_coordinate, initial_first_coordinate].map(&:stable_id))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'repetition champs' do
|
context 'with repetition champs' do
|
||||||
|
let(:tdcs) do
|
||||||
|
[
|
||||||
|
{ type: :text, libelle: 'root_first_tdc' },
|
||||||
|
{
|
||||||
|
type: :repetition,
|
||||||
|
libelle: 'root_second_tdc',
|
||||||
|
children: [
|
||||||
|
{ type: :text, libelle: 'child_first_tdc' },
|
||||||
|
{ type: :text, libelle: 'child_second_tdc' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ type: :text, libelle: 'root_thrid_tdc' }
|
||||||
|
]
|
||||||
|
end
|
||||||
|
let(:children_coordinates) { procedure.draft_revision.revision_types_de_champ.filter { _1.parent.present? } }
|
||||||
|
let(:first_child_coordinate_selector) { "##{ActionView::RecordIdentifier.dom_id(children_coordinates.first, :move_and_morph)}" }
|
||||||
|
|
||||||
|
scenario 'first child of repetition select is empty by default' do
|
||||||
|
expect(page).to have_selector("#{first_child_coordinate_selector} option", count: 1)
|
||||||
|
expect(page.find(first_child_coordinate_selector).all("option").first.value.to_s).to eq(children_coordinates.first.stable_id.to_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'when first child select is focused, seed with repetition only tdcs' do
|
||||||
|
page.find(first_child_coordinate_selector).click
|
||||||
|
expect(page).to have_selector("#{first_child_coordinate_selector} option", count: 3)
|
||||||
|
|
||||||
|
opts = page.find(first_child_coordinate_selector).all("option").map(&:text)
|
||||||
|
expect(opts).to match_array(["Selectionner une option"] + children_coordinates.map { "#{_1.position} #{_1.libelle}" })
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'when first child select is changed, move champ in repetition' do
|
||||||
|
page.find(first_child_coordinate_selector).click
|
||||||
|
expect(children_coordinates.first.position).to eq(0)
|
||||||
|
page.find(first_child_coordinate_selector).select(children_coordinates.last.libelle)
|
||||||
|
# check reorder works on backend
|
||||||
|
wait_until do
|
||||||
|
children_coordinates.first.reload.position == 1
|
||||||
|
end
|
||||||
|
# wait until turbo response
|
||||||
|
expect(page).to have_text('Formulaire enregistré')
|
||||||
|
|
||||||
|
# check reorder worked on backend
|
||||||
|
reordered_coordinates = children_coordinates.reverse
|
||||||
|
expect(procedure.reload.draft_revision.revision_types_de_champ.filter { _1.parent.present? }.sort_by(&:position).map(&:stable_id)).to eq(reordered_coordinates.map(&:stable_id))
|
||||||
|
|
||||||
|
# check reorder rerendered champ component between target->destination
|
||||||
|
reordered_coordinates.map(&:reload).map do |coordinate|
|
||||||
|
expect(page).to have_selector("##{ActionView::RecordIdentifier.dom_id(coordinate, :type_de_champ_editor)} .position", text: coordinate.position)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue