demarches-normaliennes/spec/system/users/brouillon_spec.rb

692 lines
28 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
2024-09-10 23:53:04 +02:00
describe 'The user', js: true do
let(:password) { SECURE_PASSWORD }
2018-02-21 18:32:07 +01:00
let!(:user) { create(:user, password: password) }
let!(:procedure) { create(:procedure, :published, :for_individual, :with_all_champs_mandatory) }
let(:user_dossier) { user.dossiers.first }
let!(:dossier_to_link) { create(:dossier) }
2018-02-21 18:32:07 +01:00
2024-09-10 23:53:04 +02:00
scenario 'fill a dossier', vcr: true do
log_in(user, procedure)
2018-02-21 18:32:07 +01:00
fill_individual
2024-06-21 17:03:15 +02:00
# wait for react components to be initialized
find('.dom-ready')
2018-02-21 18:32:07 +01:00
# fill data
fill_in('text', with: 'super texte', match: :first)
2018-02-21 18:32:07 +01:00
fill_in('textarea', with: 'super textarea')
2024-09-10 23:53:04 +02:00
fill_in('date', with: Date.parse('2012-12-12'), match: :first)
fill_in('datetime', with: Time.zone.parse('2023-01-06T07:05'))
2024-09-10 23:53:04 +02:00
find("input[type=datetime-local]").send_keys('ArrowUp').send_keys('ArrowDown') # triggers onChange
2024-04-11 09:49:53 +02:00
# fill_in('number', with: '42'), deadchamp, should be migrated to textchamp
fill_in('decimal_number', with: '17')
fill_in('integer_number', with: '12')
scroll_to(find_field('checkbox'), align: :center)
find('label', text: 'checkbox').click
2023-09-05 14:42:56 +02:00
find('label', text: 'Madame').click
2018-02-21 18:32:07 +01:00
fill_in('email', with: 'loulou@yopmail.com')
2020-07-29 15:45:25 +02:00
fill_in('phone', with: '0123456789')
scroll_to(find_field('Non'), align: :center)
find('label', text: 'Non').click
find('.fr-radio-group label', text: 'val2').click
find('.fr-checkbox-group label', text: 'val1').click
find('.fr-checkbox-group label', text: 'val3').click
2020-06-24 10:55:53 +02:00
select('bravo', from: form_id_for('simple_choice_drop_down_list_long'))
scroll_to(find_field('multiple_choice_drop_down_list_long'), align: :center)
fill_in('multiple_choice_drop_down_list_long', with: 'alpha')
find('.fr-menu__item', text: 'alpha').click
fill_in('multiple_choice_drop_down_list_long', with: 'charly')
find('.fr-menu__item', text: 'charly').click
wait_until { champ_value_for('multiple_choice_drop_down_list_long') == ['alpha', 'charly'].to_json }
2022-12-20 21:29:53 +01:00
select('Australie', from: form_id_for('pays'))
select('Martinique', from: form_id_for('regions'))
select('02 Aisne', from: form_id_for('departements'))
2024-06-21 17:03:15 +02:00
scroll_to(find_field('communes'), align: :center)
fill_in('communes', with: '60400')
2024-05-07 21:37:54 +02:00
find('.fr-menu__item', text: 'Brétigny (60400)').click
2023-04-26 16:49:50 +02:00
wait_until { champ_value_for('communes') == "Brétigny" }
2024-06-21 17:03:15 +02:00
scroll_to(find_field('address'), align: :center)
fill_in('address', with: '78 Rue du Grés 30310 Vergè')
2024-05-07 21:37:54 +02:00
find('.fr-menu__item', text: '78 Rue du Grés 30310 Vergèze').click
wait_until { champ_value_for('address') == '78 Rue du Grés 30310 Vergèze' }
2024-04-17 16:19:49 +02:00
wait_until { champ_for('address').full_address? }
expect(champ_for('address').departement_code_and_name).to eq('30 Gard')
# scroll_to(find_field('annuaire_education'), align: :center)
# fill_in('annuaire_education', with: 'Moulin')
# find('.fr-menu__item', text: 'Ecole primaire Jean Moulin, Moulins (0030323K)').click
# wait_until { champ_for('annuaire_education').external_id == "0030323K" }
2024-06-21 17:03:15 +02:00
fill_in('dossier_link', with: '123')
2019-02-19 17:36:02 +01:00
find('.editable-champ-piece_justificative input[type=file]').attach_file(Rails.root + 'spec/fixtures/files/file.pdf')
2018-02-21 18:32:07 +01:00
expect(page).to have_css('span', text: 'Votre brouillon est automatiquement enregistré', visible: true)
wait_for_autosave
2018-02-21 18:32:07 +01:00
# check data on the dossier
expect(user_dossier.brouillon?).to be true
expect(champ_value_for('text')).to eq('super texte')
expect(champ_value_for('textarea')).to eq('super textarea')
expect(champ_value_for('date')).to eq('2012-12-12')
expect(champ_value_for('datetime')).to eq(Time.zone.parse('2023-01-06T07:05:00').iso8601)
2024-04-11 09:49:53 +02:00
# expect(champ_value_for('number')).to eq('42'), deadchamp, should be migrated to textchamp
expect(champ_value_for('decimal_number')).to eq('17')
expect(champ_value_for('integer_number')).to eq('12')
expect(champ_value_for('checkbox')).to eq('true')
expect(champ_value_for('civilite')).to eq('Mme')
expect(champ_value_for('email')).to eq('loulou@yopmail.com')
expect(champ_value_for('phone')).to eq('0123456789')
expect(champ_value_for('yes_no')).to eq('false')
expect(champ_value_for('simple_drop_down_list')).to eq('val2')
expect(champ_value_for('simple_choice_drop_down_list_long')).to eq('bravo')
expect(JSON.parse(champ_value_for('multiple_choice_drop_down_list_long'))).to match(['alpha', 'charly'])
expect(JSON.parse(champ_value_for('multiple_drop_down_list'))).to match(['val1', 'val3'])
expect(champ_value_for('pays')).to eq('Australie')
expect(champ_value_for('regions')).to eq('Martinique')
2022-12-20 21:29:53 +01:00
expect(champ_value_for('departements')).to eq('Aisne')
2023-03-21 14:47:31 +01:00
expect(champ_value_for('communes')).to eq('Brétigny')
expect(champ_value_for('dossier_link')).to eq('123')
expect(champ_value_for('piece_justificative')).to be_nil # antivirus hasn't approved the file yet
2018-02-21 18:32:07 +01:00
## check data on the gui
2019-02-19 17:36:02 +01:00
2018-02-21 18:32:07 +01:00
expect(page).to have_field('text', with: 'super texte')
expect(page).to have_field('textarea', with: 'super textarea')
expect(page).to have_field('date', with: '2012-12-12')
expect(page).to have_field('datetime', with: '2023-01-06T07:05')
2024-04-11 09:49:53 +02:00
# expect(page).to have_field('number', with: '42'), deadchamp, should be migrated to textchamp
2018-02-21 18:32:07 +01:00
expect(page).to have_checked_field('checkbox')
expect(page).to have_checked_field('Madame')
expect(page).to have_field('email', with: 'loulou@yopmail.com')
2020-07-29 15:45:25 +02:00
expect(page).to have_field('phone', with: '0123456789')
2018-02-21 18:32:07 +01:00
expect(page).to have_checked_field('Non')
2020-06-24 10:55:53 +02:00
expect(page).to have_checked_field('val2')
expect(page).to have_checked_field('val1')
expect(page).to have_checked_field('val3')
expect(page).to have_selected_value('simple_choice_drop_down_list_long', selected: 'bravo')
2022-12-20 21:29:53 +01:00
expect(page).to have_selected_value('pays', selected: 'Australie')
expect(page).to have_selected_value('regions', selected: 'Martinique')
expect(page).to have_selected_value('departements', selected: '02 Aisne')
within("##{champ_for('multiple_choice_drop_down_list_long').input_group_id}") do
expect(page).to have_text('alpha')
expect(page).to have_text('charly')
end
expect(page).to have_field('communes', with: 'Brétigny (60400)')
2023-03-21 14:47:31 +01:00
expect(page).to have_selected_value('pays', selected: 'Australie')
expect(page).to have_field('dossier_link', with: '123')
2019-02-19 17:36:02 +01:00
expect(page).to have_text('file.pdf')
2018-02-21 18:32:07 +01:00
end
2024-09-10 23:53:04 +02:00
scenario 'fill nothing and every error anchor links points to an existing element' do
log_in(user, procedure)
fill_individual
click_on 'Déposer le dossier'
expect(page).to have_selector("#sumup-errors")
all('.error-anchor').map do |link_element|
error_anchor = URI(link_element['href'])
expect(page).to have_selector("##{error_anchor.fragment}")
end
end
2019-01-30 16:14:15 +01:00
let(:procedure_with_repetition) do
create(:procedure, :published, :for_individual, types_de_champ_public: [{ type: :repetition, mandatory: true, children: [{ libelle: 'sub type de champ' }] }])
2019-01-30 16:14:15 +01:00
end
2024-09-10 23:53:04 +02:00
scenario 'fill a dossier with repetition' do
log_in(user, procedure_with_repetition)
2019-01-30 16:14:15 +01:00
fill_individual
2020-08-27 19:56:34 +02:00
fill_in('sub type de champ', with: 'super texte')
expect(page).to have_field('sub type de champ', with: 'super texte')
2019-01-30 16:14:15 +01:00
# first repetition have a destroy hidden
expect(page).to have_selector(".repetition .row .utils-repetition-required-destroy-button", count: 1, visible: false)
expect(page).to have_selector(".repetition .row", count: 1)
# adding an element means we can ddestroy last item
click_on 'Ajouter un élément pour'
expect(page).to have_selector(".repetition .row:first-child .utils-repetition-required-destroy-button", count: 1, visible: false)
expect(page).to have_selector(".repetition .row", count: 2)
expect(page).to have_selector(".repetition .row:last-child .utils-repetition-required-destroy-button", count: 1, visible: true)
2019-01-30 16:14:15 +01:00
within '.repetition .row:first-child' do
2020-08-27 19:56:34 +02:00
fill_in('sub type de champ', with: 'un autre texte')
blur
2019-01-30 16:14:15 +01:00
end
expect do
within '.repetition .row:last-child' do
click_on 'Supprimer lélément'
end
wait_until { page.all(".row").size == 1 }
# removing a repetition means one child only, thus its button destroy is not visible
expect(page).to have_selector(".repetition .row:first-child .utils-repetition-required-destroy-button", count: 1, visible: false)
end.to change { Champ.count }
2019-01-30 16:14:15 +01:00
end
let(:simple_procedure) {
create(:procedure, :published, :for_individual, types_de_champ_public: [
{ mandatory: true, libelle: 'texte obligatoire' }, { mandatory: false, libelle: 'texte optionnel' },
{ mandatory: false, libelle: "nombre entier", type: :integer_number },
{ mandatory: false, libelle: "nombre décimal", type: :decimal_number },
{ mandatory: false, libelle: 'address', type: :address },
{ mandatory: false, libelle: 'IBAN', type: :iban }
])
}
2018-02-21 18:32:07 +01:00
2024-09-10 23:53:04 +02:00
scenario 'save an incomplete dossier as draft but cannot not submit it' do
log_in(user, simple_procedure)
2018-02-21 18:32:07 +01:00
fill_individual
2018-07-02 12:27:01 +02:00
# Check an incomplete dossier can be saved as a draft, even when mandatory fields are missing
2020-09-15 13:38:45 +02:00
fill_in('texte optionnel', with: 'ça ne suffira pas')
wait_for_autosave
expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
2018-02-21 18:32:07 +01:00
fill_in('IBAN', with: 'FR')
wait_until { champ_value_for('IBAN') == 'FR' }
expect(page).not_to have_content 'nest pas au format IBAN'
blur
expect(page).to have_content 'nest pas au format IBAN'
fill_in('IBAN', with: 'FR7630006000011234567890189')
wait_until { champ_value_for('IBAN') == 'FR76 3000 6000 0112 3456 7890 189' }
expect(page).not_to have_content 'nest pas au format IBAN'
2018-07-02 12:27:01 +02:00
# Check an incomplete dossier cannot be submitted when mandatory fields are missing
2019-07-15 16:10:34 +02:00
click_on 'Déposer le dossier'
2018-02-21 18:32:07 +01:00
expect(user_dossier.reload.brouillon?).to be(true)
expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
2018-02-21 18:32:07 +01:00
2018-07-02 12:27:01 +02:00
# Check a dossier can be submitted when all mandatory fields are filled
fill_in('texte obligatoire', with: 'super texte')
wait_until { champ_value_for('texte obligatoire') == 'super texte' }
2018-02-21 18:32:07 +01:00
2019-07-15 16:10:34 +02:00
click_on 'Déposer le dossier'
wait_until { user_dossier.reload.en_construction? }
2018-02-27 09:49:58 +01:00
expect(page).to have_current_path(merci_dossier_path(user_dossier))
2018-02-21 18:32:07 +01:00
end
2024-09-10 23:53:04 +02:00
scenario 'fill address not in BAN' do
log_in(user, simple_procedure)
fill_individual
fill_in('address', with: '2 rue de la paix, 92094 Belgique')
wait_until {
champ_value_for('address') == '2 rue de la paix, 92094 Belgique'
}
expect(champ_for('address').full_address?).to be_falsey
end
2024-09-10 23:53:04 +02:00
scenario 'numbers champs formatting' do
log_in(user, simple_procedure)
fill_individual
fill_in('nombre entier', with: '300 environ')
wait_until {
champ_value_for('nombre entier') == '300'
}
fill_in('nombre entier', with: '-256')
wait_until {
champ_value_for('nombre entier') == '-256'
}
fill_in('nombre décimal', with: '123 456,78')
wait_until {
champ_value_for('nombre décimal') == '123456.78'
}
champ_past_value_for('nombre décimal', '123 456,78')
wait_until {
champ_value_for('nombre décimal') == '123456.78'
}
fill_in('nombre décimal', with: '123 456.78')
wait_until {
champ_value_for('nombre décimal') == '123456.78'
}
champ_past_value_for('nombre décimal', '123 456.78')
wait_until {
champ_value_for('nombre décimal') == '123456.78'
}
fill_in('nombre décimal', with: '123 456.002')
wait_until {
champ_value_for('nombre décimal') == '123456.002'
}
fill_in('nombre décimal', with: '123 456,002')
wait_until {
champ_value_for('nombre décimal') == '123456.002'
}
champ_past_value_for('nombre décimal', '1,234.56')
wait_until {
champ_value_for('nombre décimal') == '1234.56'
}
champ_past_value_for('nombre décimal', '-1,234.56')
wait_until {
champ_value_for('nombre décimal') == '-1234.56'
}
champ_past_value_for('nombre décimal', '1.234,56')
wait_until {
champ_value_for('nombre décimal') == '1234.56'
}
end
2024-09-10 23:53:04 +02:00
scenario 'extends dossier experation date more than one time, ' do
simple_procedure.update(procedure_expires_when_termine_enabled: true)
user_old_dossier = create(:dossier,
procedure: simple_procedure,
created_at: simple_procedure.duree_conservation_dossiers_dans_ds.month.ago,
user: user)
login_as(user, scope: :user)
visit brouillon_dossier_path(user_old_dossier)
expect(page).to have_css('.fr-callout__title', text: 'Votre dossier a expiré', visible: true)
find('#test-user-repousser-expiration').click
expect(page).to have_no_selector('#test-user-repousser-expiration')
Timecop.freeze(simple_procedure.duree_conservation_dossiers_dans_ds.month.from_now) do
visit brouillon_dossier_path(user_old_dossier)
expect(page).to have_css('.fr-callout__title', text: 'Votre dossier a expiré', visible: true)
find('#test-user-repousser-expiration').click
expect(page).to have_no_selector('#test-user-repousser-expiration')
end
end
let(:procedure_with_pj) { create(:procedure, :published, :for_individual, types_de_champ_public: [{ type: :piece_justificative, mandatory: true, libelle: 'Pièce justificative' }]) }
let(:procedure_with_pjs) { create(:procedure, :published, :for_individual, types_de_champ_public: [{ type: :piece_justificative, mandatory: true, libelle: 'Pièce justificative 1' }, { type: :piece_justificative, mandatory: true, libelle: 'Pièce justificative 2' }]) }
let(:old_procedure_with_disabled_pj_validation) { create(:procedure, :published, :for_individual, types_de_champ_public: [{ type: :piece_justificative, mandatory: true, libelle: 'Pièce justificative 1', skip_pj_validation: true }]) }
2024-09-10 23:53:04 +02:00
scenario 'add an attachment' do
log_in(user, procedure_with_pjs)
2019-02-19 17:36:02 +01:00
fill_individual
# Add attachments
find_field('Pièce justificative 1').attach_file(Rails.root + 'spec/fixtures/files/file.pdf')
find_field('Pièce justificative 2').attach_file(Rails.root + 'spec/fixtures/files/RIB.pdf')
2019-02-19 17:36:02 +01:00
# Expect the files to be uploaded immediately
expect(page).to have_text('file.pdf')
2019-02-19 17:36:02 +01:00
expect(page).to have_text('RIB.pdf')
expect(page).to have_button("Supprimer", title: "Supprimer le fichier RIB.pdf")
2019-02-19 17:36:02 +01:00
# Expect the submit buttons to be enabled
expect(page).to have_button('Déposer le dossier', disabled: false)
2019-02-19 17:36:02 +01:00
# Reload the current page
visit current_path
# Expect the files to have been saved on the dossier
expect(page).to have_text('file.pdf')
expect(page).to have_text('RIB.pdf')
end
2024-09-10 23:53:04 +02:00
scenario 'add an invalid attachment on an old procedure where pj validation is disabled' do
log_in(user, old_procedure_with_disabled_pj_validation)
fill_individual
# Test invalid file type
attach_file('Pièce justificative 1', Rails.root + 'spec/fixtures/files/invalid_file_format.json')
expect(page).to have_no_text('La pièce justificative nest pas dun type accepté')
end
2024-09-10 23:53:04 +02:00
scenario 'retry on transcient upload error' do
log_in(user, procedure_with_pjs)
fill_individual
# Test auto-upload failure
# Make the subsequent auto-upload request fail
allow_any_instance_of(Champs::PieceJustificativeController).to receive(:update) do |instance|
instance.render json: { errors: ["Une erreur est survenue"] }, status: :bad_request
end
attach_file('Pièce justificative 1', Rails.root + 'spec/fixtures/files/file.pdf')
expect(page).to have_css('p', text: "Une erreur est survenue", visible: :visible, wait: 5)
expect(page).to have_button('Réessayer', visible: true)
expect(page).to have_button('Déposer le dossier', disabled: false)
allow_any_instance_of(Champs::PieceJustificativeController).to receive(:update).and_call_original
# Test that retrying after a failure works
click_on('Réessayer', visible: true, wait: 5)
expect(page).to have_text('file.pdf')
expect(page).to have_button('Déposer le dossier', disabled: false)
expect(page).to have_button("Supprimer", title: "Supprimer le fichier file.pdf")
# Reload the current page
visit current_path
# Expect the file to have been saved on the dossier
expect(page).to have_text('file.pdf')
end
2024-09-10 23:53:04 +02:00
scenario "upload multiple pieces justificatives on same champ" do
log_in(user, procedure_with_pjs)
fill_individual
attach_file('Pièce justificative 1', Rails.root + 'spec/fixtures/files/file.pdf')
expect(page).to have_text('file.pdf')
attach_file('Pièce justificative 1', Rails.root + 'spec/fixtures/files/white.png')
expect(page).to have_text('white.png')
click_on("Supprimer le fichier file.pdf")
2022-12-06 16:32:50 +01:00
expect(page).not_to have_text('file.pdf')
expect(page).to have_text("La pièce jointe a bien été supprimée")
attach_file('Pièce justificative 1', Rails.root + 'spec/fixtures/files/black.png')
# Mark all attachments as safe to test turbo poll
# They are not immediately attached in db, so we have to wait a bit before continuing
2022-12-06 16:32:50 +01:00
# NOTE: we're using files not used in other tests to avoid conflicts with concurrent tests
attachments = Timeout.timeout(5) do
filenames = ['white.png', 'black.png']
attachments = ActiveStorage::Attachment.where(name: "piece_justificative_file").includes(:blob).filter do |attachment|
filenames.include?(attachment.filename.to_s)
end
fail ActiveRecord::RecordNotFound, "Not all attachments where found yet" unless attachments.count == filenames.count
attachments
rescue ActiveRecord::RecordNotFound
sleep 0.2
retry
end
attachments.each {
_1.blob.virus_scan_result = ActiveStorage::VirusScanner::SAFE
_1.save!
}
visit current_path
2022-12-06 16:32:50 +01:00
expect(page).not_to have_text('file.pdf')
expect(page).to have_text('white.png')
expect(page).to have_text('black.png')
end
context 'with condition' do
include Logic
context 'with a repetition' do
let(:stable_id) { 999 }
let(:condition) { greater_than_eq(champ_value(stable_id), constant(18)) }
let(:procedure) do
create(:procedure, :published, :for_individual,
types_de_champ_public: [
{ type: :integer_number, libelle: 'age', mandatory: false, stable_id: },
{
type: :repetition, libelle: 'repetition', condition:, children: [
{ type: :text, libelle: 'nom', mandatory: true }
]
}
])
end
2024-09-10 23:53:04 +02:00
scenario 'submit a dossier with an hidden mandatory champ within a repetition' do
log_in(user, procedure)
fill_individual
fill_in('age (facultatif)', with: 10)
click_on 'Déposer le dossier'
expect(page).to have_current_path(merci_dossier_path(user_dossier))
end
end
context 'with a condition inside repetition' do
let(:a_stable_id) { 999 }
let(:b_stable_id) { 9999 }
let(:a_condition) { ds_eq(champ_value(a_stable_id), constant(true)) }
let(:b_condition) { ds_eq(champ_value(b_stable_id), constant(true)) }
let(:condition) { ds_or([a_condition, b_condition]) }
2022-08-08 17:11:20 +02:00
let(:procedure) do
create(:procedure, :published, :for_individual,
types_de_champ_public: [
{ type: :checkbox, libelle: 'champ_a', mandatory: false, stable_id: a_stable_id },
{
type: :repetition, libelle: 'repetition', mandatory: true, children: [
{ type: :checkbox, libelle: 'champ_b', stable_id: b_stable_id },
{ type: :text, libelle: 'champ_c', condition: }
]
}
])
end
2022-08-08 17:11:20 +02:00
2024-09-10 23:53:04 +02:00
scenario 'fill a dossier' do
log_in(user, procedure)
2022-08-08 17:11:20 +02:00
fill_individual
expect(page).to have_no_css('label', text: 'champ_c', visible: true)
find('label', text: 'champ_a').click # check
wait_for_autosave
expect(page).to have_css('label', text: 'champ_c', visible: true)
find('label', text: 'champ_a').click # uncheck
wait_for_autosave
expect(page).to have_no_css('label', text: 'champ_c', visible: true)
find('label', text: 'champ_b').click # check
wait_for_autosave
expect(page).to have_css('label', text: 'champ_c', visible: true)
end
end
context 'with a required conditionnal champ' do
let(:stable_id) { 999 }
let(:condition) { greater_than_eq(champ_value(stable_id), constant(18)) }
let(:procedure) do
create(:procedure, :published, :for_individual,
types_de_champ_public: [
{ type: :integer_number, libelle: 'age', mandatory: false, stable_id: },
{ type: :text, libelle: 'nom', mandatory: true, condition: }
])
2022-08-08 17:11:20 +02:00
end
2024-09-10 23:53:04 +02:00
scenario 'submit a dossier with an hidden mandatory champ ' do
2022-08-08 17:11:20 +02:00
log_in(user, procedure)
fill_individual
2022-08-08 17:11:20 +02:00
click_on 'Déposer le dossier'
expect(page).to have_current_path(merci_dossier_path(user_dossier))
end
2024-09-10 23:53:04 +02:00
scenario 'cannot submit a reveal dossier with a revealed mandatory champ ' do
log_in(user, procedure)
fill_individual
fill_in('age (facultatif)', with: '18')
expect(page).to have_css('label', text: 'nom', visible: :visible)
expect(page).to have_css('.icon.mandatory')
click_on 'Déposer le dossier'
expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
end
2022-08-08 17:11:20 +02:00
end
2022-08-08 16:27:02 +02:00
context 'with a visibilite in cascade' do
let(:age_stable_id) { 999 }
let(:permis_stable_id) { 9999 }
let(:tonnage_stable_id) { 99999 }
let(:permis_condition) { greater_than_eq(champ_value(age_stable_id), constant(18)) }
let(:tonnage_condition) { ds_eq(champ_value(permis_stable_id), constant(true)) }
let(:parking_condition) { less_than_eq(champ_value(tonnage_stable_id), constant(20)) }
let(:procedure) do
create(:procedure, :published, :for_individual,
types_de_champ_public: [
{ type: :integer_number, libelle: 'age du candidat', stable_id: age_stable_id, mandatory: false },
{ type: :yes_no, libelle: 'permis de conduire', stable_id: permis_stable_id, condition: permis_condition, mandatory: false },
{ type: :header_section, libelle: 'info voiture', condition: permis_condition, mandatory: false },
{ type: :integer_number, libelle: 'tonnage', stable_id: tonnage_stable_id, condition: tonnage_condition, mandatory: false },
{ type: :text, libelle: 'parking', condition: parking_condition, mandatory: false }
])
2022-08-08 16:27:02 +02:00
end
2024-09-10 23:53:04 +02:00
scenario 'fill a dossier' do
2022-08-08 16:27:02 +02:00
log_in(user, procedure)
2022-08-08 16:27:02 +02:00
fill_individual
expect(page).to have_css('label', text: 'age du candidat', visible: true)
expect(page).to have_no_css('legend', text: 'permis de conduire', visible: true)
expect(page).to have_no_css('legend', text: 'info voiture', visible: true)
2022-08-08 16:27:02 +02:00
expect(page).to have_no_css('label', text: 'tonnage', visible: true)
2022-07-20 10:58:03 +02:00
fill_in('age du candidat (facultatif)', with: '18')
expect(page).to have_css('legend', text: 'permis de conduire', visible: true)
expect(page).to have_css('legend', text: 'info voiture', visible: true)
2022-08-08 16:27:02 +02:00
expect(page).to have_no_css('label', text: 'tonnage', visible: true)
2022-07-20 10:58:03 +02:00
page.find('label', text: 'Oui').click
expect(page).to have_css('legend', text: 'permis de conduire', visible: true)
2022-08-08 16:27:02 +02:00
expect(page).to have_css('label', text: 'tonnage', visible: true)
2022-07-20 10:58:03 +02:00
2022-08-08 16:27:02 +02:00
fill_in('tonnage', with: '1')
expect(page).to have_css('label', text: 'parking', visible: true)
2022-08-08 16:27:02 +02:00
# try to fill with invalid data
fill_in('tonnage (facultatif)', with: 'a')
2022-08-08 16:27:02 +02:00
expect(page).to have_no_css('label', text: 'parking', visible: true)
fill_in('age du candidat (facultatif)', with: '2')
expect(page).to have_no_css('legend', text: 'permis de conduire', visible: true)
2022-08-08 16:27:02 +02:00
expect(page).to have_no_css('label', text: 'tonnage', visible: true)
2022-08-08 16:27:02 +02:00
click_on 'Déposer le dossier'
click_on 'Accéder à votre dossier'
click_on 'Modifier mon dossier'
expect(page).to have_css('label', text: 'age du candidat', visible: true)
expect(page).to have_no_css('legend', text: 'permis de conduire', visible: true)
2022-08-08 16:27:02 +02:00
expect(page).to have_no_css('label', text: 'tonnage', visible: true)
2022-07-20 10:58:03 +02:00
fill_in('age du candidat (facultatif)', with: '18')
wait_for_autosave
2022-08-08 16:27:02 +02:00
# the champ keeps their previous value so they are all displayed
expect(page).to have_css('legend', text: 'permis de conduire', visible: true)
2022-08-08 16:27:02 +02:00
expect(page).to have_css('label', text: 'tonnage', visible: true)
end
end
end
2020-09-14 22:40:43 +02:00
context 'draft autosave' do
2024-09-10 23:53:04 +02:00
scenario 'autosave a draft' do
2019-11-19 14:40:28 +01:00
log_in(user, simple_procedure)
fill_individual
expect(page).to have_no_button('Enregistrer le brouillon')
2019-11-19 14:40:28 +01:00
expect(page).to have_content('Votre brouillon est automatiquement enregistré')
fill_in('texte obligatoire', with: 'a valid user input')
wait_for_autosave
2023-05-10 13:54:12 +02:00
wait_until { champ_value_for('texte obligatoire') == 'a valid user input' }
2019-11-19 14:40:28 +01:00
visit current_path
expect(page).to have_field('texte obligatoire', with: 'a valid user input')
end
2024-09-10 23:53:04 +02:00
scenario 'retry on autosave error', :capybara_ignore_server_errors do
2019-11-19 14:40:28 +01:00
log_in(user, simple_procedure)
fill_individual
# Test autosave failure
allow_any_instance_of(Users::DossiersController).to receive(:update).and_raise("Server is busy")
2019-11-19 14:40:28 +01:00
fill_in('texte obligatoire', with: 'a valid user input')
blur
expect(page).to have_css('span', text: 'Impossible denregistrer le brouillon', visible: true)
# Test that retrying after a failure works
allow_any_instance_of(Users::DossiersController).to receive(:update).and_call_original
2023-04-21 18:38:00 +02:00
click_on 'Réessayer'
wait_for_autosave
2023-05-10 13:54:12 +02:00
wait_until { champ_value_for('texte obligatoire') == 'a valid user input' }
2019-11-19 14:40:28 +01:00
visit current_path
expect(page).to have_field('texte obligatoire', with: 'a valid user input')
end
2024-09-10 23:53:04 +02:00
scenario 'autosave redirects to sign-in after being disconnected' do
log_in(user, simple_procedure)
fill_individual
# When the user is disconnected
# (either because signing-out in another tab, or because the session cookie expired)
logout(:user)
fill_in('texte obligatoire', with: 'a valid user input')
# … they are redirected to the sign-in page.
expect(page).to have_current_path(new_user_session_path)
# After sign-in, they are redirected back to their brouillon
sign_in_with(user.email, password)
expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
fill_in('texte obligatoire', with: 'a valid user input')
wait_for_autosave
end
2019-11-19 14:40:28 +01:00
end
2018-02-21 18:32:07 +01:00
private
def log_in(user, procedure)
login_as user, scope: :user
2018-02-21 18:32:07 +01:00
visit "/commencer/#{procedure.path}"
click_on 'Commencer la démarche'
2023-11-23 16:38:01 +01:00
expect(page).to have_content("Votre identité")
2018-02-21 18:32:07 +01:00
expect(page).to have_current_path(identite_dossier_path(user_dossier))
end
def champ_value_for(libelle)
champ_for(libelle).value
end
def champ_id_for(libelle)
champ_for(libelle).input_id
end
def champ_past_value_for(libelle, value)
execute_script("{
let target = document.querySelector('##{champ_id_for(libelle)}');
target.value = \"#{value}\";
target.dispatchEvent(new CustomEvent('input', { bubbles: true }));
}")
end
def champ_for(libelle)
champs = user_dossier.reload.project_champs_public
2024-07-22 16:29:20 +02:00
champ = champs.find { |c| c.libelle == libelle }
champ.reload
2018-02-21 18:32:07 +01:00
end
def fill_individual
find('label', text: 'Monsieur').click
2023-11-23 16:38:01 +01:00
fill_in('Prénom', with: 'prenom', visible: true)
fill_in('Nom', with: 'Nom', visible: true)
2024-04-12 17:59:50 +02:00
within "#identite-form" do
click_on 'Continuer'
end
expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
2018-02-21 18:32:07 +01:00
end
end