Merge pull request #1463 from betagouv/new_form

[Fix #1411] Nouveau formulaire usager
This commit is contained in:
LeSim 2018-02-27 15:46:50 +01:00 committed by GitHub
commit 51022711ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 489 additions and 131 deletions

View file

@ -42,4 +42,16 @@ addEventListener("direct-upload:end", function (event) {
element = document.getElementById("direct-upload-" + id); element = document.getElementById("direct-upload-" + id);
element.classList.add("direct-upload--complete"); element.classList.add("direct-upload--complete");
}); });
addEventListener('load', function() {
var submitButtons = document.querySelectorAll('form button[type=submit][data-action]');
var hiddenInput = document.querySelector('form input[type=hidden][name=submit_action]');
submitButtons = [].slice.call(submitButtons);
submitButtons.forEach(function(button) {
button.addEventListener('click', function() {
hiddenInput.value = button.getAttribute('data-action');
});
});
});

View file

@ -0,0 +1,20 @@
@import "colors";
@import "constants";
.dossier-edit {
.dossier-header {
background-color: $light-grey;
.container {
padding: $default-padding;
}
h1 {
font-size: 22px;
}
}
.thanks {
padding: (1.5 * $default-padding) 0;
}
}

View file

@ -15,6 +15,7 @@
label { label {
margin-bottom: $default-padding; margin-bottom: $default-padding;
display: block; display: block;
font-weight: bold;
.mandatory { .mandatory {
color: $dark-red; color: $dark-red;
@ -115,7 +116,7 @@
input.touched:invalid, input.touched:invalid,
textarea.touched:invalid { textarea.touched:invalid {
border-color: $dark-red; border: 1px solid $dark-red;
box-shadow: 0px 0px 5px $dark-red; box-shadow: 0px 0px 5px $dark-red;
} }
@ -239,4 +240,15 @@
margin-right: 0; margin-right: 0;
} }
} }
.pj-input {
input[type=file] {
margin: $default-padding 0 (2 * $default-padding);
padding: 2px;
}
.piece-description {
margin-bottom: $default-padding;
}
}
} }

View file

@ -23,7 +23,7 @@ module NewUser
if @dossier.procedure.module_api_carto.use_api_carto if @dossier.procedure.module_api_carto.use_api_carto
redirect_to users_dossier_carte_path(@dossier.id) redirect_to users_dossier_carte_path(@dossier.id)
else else
redirect_to users_dossier_description_path(@dossier) # Simon should replace this with dossier_path when done redirect_to modifier_dossier_path(@dossier)
end end
else else
flash.now.alert = @dossier.errors.full_messages flash.now.alert = @dossier.errors.full_messages
@ -31,12 +31,62 @@ module NewUser
end end
end end
def modifier
@dossier = dossier_with_champs
# TODO: remove when the champs are unifed
if !@dossier.autorisation_donnees
if dossier.procedure.for_individual
redirect_to identite_dossier_path(@dossier)
else
redirect_to users_dossier_path(@dossier)
end
end
end
# FIXME: remove PiecesJustificativesService
# delegate draft save logic to champ ?
def update
@dossier = dossier_with_champs
errors = PiecesJustificativesService.upload!(@dossier, current_user, params)
if !@dossier.update(champs_params)
errors += @dossier.errors.full_messages
end
if !draft?
errors += @dossier.champs.select(&:mandatory_and_blank?)
.map { |c| "Le champ #{c.libelle.truncate(200)} doit être rempli." }
errors += PiecesJustificativesService.missing_pj_error_messages(@dossier)
end
if errors.present?
flash.now.alert = errors
render :modifier
elsif draft?
flash.now.notice = 'Votre brouillon a bien été sauvegardé.'
render :modifier
else
@dossier.en_construction!
redirect_to users_dossier_recapitulatif_path(@dossier)
end
end
private private
def champs_params
params.require(:dossier).permit(champs_attributes: [:id, :value, :piece_justificative_file, value: []])
end
def dossier def dossier
Dossier.find(params[:id] || params[:dossier_id]) Dossier.find(params[:id] || params[:dossier_id])
end end
def dossier_with_champs
@dossier_with_champs ||= current_user.dossiers.includes(champs: :type_de_champ).find(params[:id])
end
def ensure_ownership! def ensure_ownership!
if dossier.user != current_user if dossier.user != current_user
flash[:alert] = "Vous n'avez pas accès à ce dossier" flash[:alert] = "Vous n'avez pas accès à ce dossier"
@ -51,5 +101,9 @@ module NewUser
def dossier_params def dossier_params
params.require(:dossier).permit(:autorisation_donnees) params.require(:dossier).permit(:autorisation_donnees)
end end
def draft?
params[:submit_action] == 'draft'
end
end end
end end

View file

@ -24,10 +24,7 @@ class Users::CarteController < UsersController
dossier.update_attributes(json_latlngs: params[:json_latlngs]) dossier.update_attributes(json_latlngs: params[:json_latlngs])
controller = :recapitulatif redirect_to modifier_dossier_path(dossier)
controller = :description if dossier.brouillon?
redirect_to url_for(controller: controller, action: :show, dossier_id: params[:dossier_id])
end end
def get_position def get_position

View file

@ -154,7 +154,7 @@ class Users::DossiersController < UsersController
if @facade.dossier.procedure.module_api_carto.use_api_carto if @facade.dossier.procedure.module_api_carto.use_api_carto
redirect_to url_for(controller: :carte, action: :show, dossier_id: @facade.dossier.id) redirect_to url_for(controller: :carte, action: :show, dossier_id: @facade.dossier.id)
else else
redirect_to url_for(controller: :description, action: :show, dossier_id: @facade.dossier.id) redirect_to modifier_dossier_path(@facade.dossier)
end end
end end
end end

View file

@ -16,14 +16,6 @@ class DossierDecorator < Draper::Decorator
DossierDecorator.case_state_fr state DossierDecorator.case_state_fr state
end end
def url(gestionnaire_signed_in)
if brouillon?
users_dossier_description_path(id)
else
users_dossier_recapitulatif_path(id)
end
end
def self.case_state_fr state = self.state def self.case_state_fr state = self.state
h.t("activerecord.attributes.dossier.state.#{state}") h.t("activerecord.attributes.dossier.state.#{state}")
end end

View file

@ -108,6 +108,10 @@ class Dossier < ActiveRecord::Base
champs.joins(', types_de_champ').where("champs.type_de_champ_id = types_de_champ.id AND types_de_champ.procedure_id = #{procedure.id}").order('order_place') champs.joins(', types_de_champ').where("champs.type_de_champ_id = types_de_champ.id AND types_de_champ.procedure_id = #{procedure.id}").order('order_place')
end end
def ordered_champs_v2
champs.includes(:type_de_champ).order('types_de_champ.order_place')
end
def ordered_champs_private def ordered_champs_private
# TODO: use the line below when the procedure preview does not leak champ with dossier_id == 0 # TODO: use the line below when the procedure preview does not leak champ with dossier_id == 0
# champs_private.includes(:type_de_champ).order('types_de_champ.order_place') # champs_private.includes(:type_de_champ).order('types_de_champ.order_place')

View file

@ -1,5 +1,5 @@
- if !@facade.dossier.read_only? - if !@facade.dossier.read_only?
- if user_signed_in? && (@facade.dossier.owner?(current_user.email) || @facade.dossier.invite_by_user?(current_user.email)) - if user_signed_in? && (@facade.dossier.owner?(current_user.email) || @facade.dossier.invite_by_user?(current_user.email))
%a#maj_infos.action{ href: "/users/dossiers/#{@facade.dossier.id}/description" } = link_to modifier_dossier_path(@facade.dossier), class: 'action', id: 'maj_infos' do
#edit-dossier.col-lg-2.col-md-2.col-sm-2.col-xs-2.action #edit-dossier.col-lg-2.col-md-2.col-sm-2.col-xs-2.action
= "éditer".upcase = "éditer".upcase

View file

@ -41,7 +41,7 @@
- if champ.type_champ == 'dossier_link' - if champ.type_champ == 'dossier_link'
- dossier = Dossier.includes(:procedure).find_by(id: champ.decorate.value) - dossier = Dossier.includes(:procedure).find_by(id: champ.decorate.value)
- if dossier - if dossier
= link_to("Dossier #{dossier.id}", dossier.decorate.url(gestionnaire_signed_in?), target: '_blank') = link_to("Dossier #{dossier.id}", modifier_dossier_path(dossier), target: '_blank')
%br %br
= sanitize(dossier.text_summary) = sanitize(dossier.text_summary)
- else - else

View file

@ -30,6 +30,11 @@
%br %br
par email : <a href="mailto:contact@tps.apientreprise.fr">contact@tps.apientreprise.fr</a> par email : <a href="mailto:contact@tps.apientreprise.fr">contact@tps.apientreprise.fr</a>
- if nav_bar_profile == :user
%ul.header-tabs
%li
= link_to "Mes dossiers", users_dossiers_path, class: 'tab-link'
%ul.header-right-content %ul.header-right-content
- if nav_bar_profile == :gestionnaire && gestionnaire_signed_in? - if nav_bar_profile == :gestionnaire && gestionnaire_signed_in?
%li %li

View file

@ -3,7 +3,7 @@
- if champ.mandatory? - if champ.mandatory?
%span.mandatory * %span.mandatory *
- if champ.updated_at.present? - if champ.updated_at.present? && seen_at.present?
%span.updated-at{ class: highlight_if_unseen_class(seen_at, champ.updated_at) } %span.updated-at{ class: highlight_if_unseen_class(seen_at, champ.updated_at) }
= "modifié le #{champ.updated_at.strftime('%d/%m/%Y à %H:%M')}" = "modifié le #{champ.updated_at.strftime('%d/%m/%Y à %H:%M')}"

View file

@ -1,6 +1,6 @@
.editable-champ .editable-champ
- if is_not_header_nor_explication?(champ) - if is_not_header_nor_explication?(champ)
= render partial: 'new_gestionnaire/dossiers/editable_champs/champ_label', locals: { form: form, champ: champ, seen_at: seen_at } = render partial: 'new_gestionnaire/dossiers/editable_champs/champ_label', locals: { form: form, champ: champ, seen_at: defined?(seen_at) ? seen_at : nil }
= render partial: "new_gestionnaire/dossiers/editable_champs/#{champ.type_champ}", = render partial: "new_gestionnaire/dossiers/editable_champs/#{champ.type_champ}",
locals: { champ: champ, form: form } locals: { champ: champ, form: form }

View file

@ -0,0 +1,62 @@
.dossier-edit
.dossier-header
.container
%h1= @dossier.procedure.libelle
.container
%p.thanks Les champs avec une asterisque (*) sont obligatoires.
= form_for @dossier, html: { class: 'form', multipart: true } do |f|
= f.fields_for :champs, @dossier.ordered_champs_v2 do |champ_form|
- champ = champ_form.object
= render partial: "new_gestionnaire/dossiers/editable_champs/editable_champ",
locals: { champ: champ, form: champ_form }
- tpjs = @dossier.types_de_piece_justificative.order('order_place ASC')
- if tpjs.present?
.card.featured
.card-title
Pièces-jointes
- tpjs.each do |tpj|
.pj-input
%label{ for: "piece_justificative_#{tpj.id}" }
= tpj.libelle
- if tpj.mandatory?
%span.mandatory *
%p.piece-description= tpj.description
- if tpj.lien_demarche.present?
%p.piece-description
Récupérer le formulaire vierge pour mon dossier :
= link_to "Télécharger", tpj.lien_demarche, target: :blank
- if @dossier.was_piece_justificative_uploaded_for_type_id?(tpj.id)
- pj = @dossier.retrieve_last_piece_justificative_by_type(tpj.id)
%p
Pièce-jointe déjà importée :
= link_to pj.original_filename, pj.content_url, target: :blank
= file_field_tag "piece_justificative_#{tpj.id}",
accept: PieceJustificative.accept_format,
max_file_size: 6.megabytes,
required: (tpj.mandatory? && !@dossier.was_piece_justificative_uploaded_for_type_id?(tpj.id))
.send-wrapper
= hidden_field_tag 'submit_action', 'draft'
- if @dossier.brouillon?
= f.button 'Enregistrer le brouillon',
formnovalidate: true,
class: 'button send',
data: { action: 'draft', disable_with: 'Envoi...' }
= f.button 'Soumettre le dossier',
class: 'button send primary',
data: { action: 'submit', disable_with: 'Envoi...' }
- else
= f.button 'Modifier le dossier',
class: 'button send primary',
data: { action: 'submit', disable_with: 'Envoi...' }

View file

@ -17,7 +17,7 @@
- dossier_url = users_dossiers_invite_path(id: invite.id) if invite.present? - dossier_url = users_dossiers_invite_path(id: invite.id) if invite.present?
- if invite.nil? - if invite.nil?
- dossier_url = users_dossier_recapitulatif_path(dossier) if !dossier.brouillon? - dossier_url = users_dossier_recapitulatif_path(dossier) if !dossier.brouillon?
- dossier_url = users_dossier_description_path(dossier) if dossier.brouillon? - dossier_url = modifier_dossier_path(dossier) if dossier.brouillon?
%tr{ id: "tr_dossier_#{dossier.id}", 'data-dossier_url' => dossier_url } %tr{ id: "tr_dossier_#{dossier.id}", 'data-dossier_url' => dossier_url }
%td.center %td.center

View file

@ -202,10 +202,11 @@ Rails.application.routes.draw do
get "patron" => "root#patron" get "patron" => "root#patron"
scope module: 'new_user' do scope module: 'new_user' do
resources :dossiers, only: [] do resources :dossiers, only: [:update] do
member do member do
get 'identite' get 'identite'
patch 'update_identite' patch 'update_identite'
get 'modifier'
end end
get 'attestation' get 'attestation'
end end

View file

@ -81,7 +81,7 @@ describe NewUser::DossiersController, type: :controller do
let(:dossier_params) { { autorisation_donnees: true } } let(:dossier_params) { { autorisation_donnees: true } }
it do it do
expect(response).to redirect_to(users_dossier_description_path(dossier)) expect(response).to redirect_to(modifier_dossier_path(dossier))
end end
context 'on a procedure with carto' do context 'on a procedure with carto' do
@ -103,4 +103,114 @@ describe NewUser::DossiersController, type: :controller do
end end
end end
end end
describe '#modifier' do
before { sign_in(user) }
let!(:dossier) { create(:dossier, user: user, autorisation_donnees: true) }
subject { get :modifier, params: { id: dossier.id } }
context 'when autorisation_donnees is checked' do
it { is_expected.to render_template(:modifier) }
end
context 'when autorisation_donnees is not checked' do
before { dossier.update_columns(autorisation_donnees: false) }
context 'when the dossier is for personne morale' do
it { is_expected.to redirect_to(users_dossier_path(dossier)) }
end
context 'when the dossier is for an personne physique' do
before { dossier.procedure.update_attributes(for_individual: true) }
it { is_expected.to redirect_to(identite_dossier_path(dossier)) }
end
end
end
describe '#edit' do
before { sign_in(user) }
let!(:dossier) { create(:dossier, user: user) }
it 'returns the edit page' do
get :modifier, params: { id: dossier.id }
expect(response).to have_http_status(:success)
end
end
describe '#update' do
before { sign_in(user) }
let!(:dossier) { create(:dossier, user: user) }
let(:first_champ) { dossier.champs.first }
let(:value) { 'beautiful value' }
let(:submit_payload) do
{
id: dossier.id,
dossier: {
champs_attributes: {
id: first_champ.id,
value: value
}
}
}
end
let(:payload) { submit_payload }
subject { patch :update, params: payload }
it 'updates the champs' do
subject
expect(response).to redirect_to(users_dossier_recapitulatif_path(dossier))
expect(first_champ.reload.value).to eq('beautiful value')
expect(dossier.reload.state).to eq('en_construction')
end
context 'when the update fails' do
before do
expect_any_instance_of(Dossier).to receive(:update).and_return(false)
expect_any_instance_of(Dossier).to receive(:errors)
.and_return(double(full_messages: ['nop']))
subject
end
it { expect(response).to render_template(:modifier) }
it { expect(flash.alert).to eq(['nop']) }
end
context 'when the pj service returns an error' do
before do
expect(PiecesJustificativesService).to receive(:upload!).and_return(['nop'])
subject
end
it { expect(response).to render_template(:modifier) }
it { expect(flash.alert).to eq(['nop']) }
end
context 'when a mandatory champ is missing' do
let(:value) { nil }
before do
first_champ.type_de_champ.update_attributes(mandatory: true, libelle: 'l')
allow(PiecesJustificativesService).to receive(:missing_pj_error_messages).and_return(['pj'])
subject
end
it { expect(response).to render_template(:modifier) }
it { expect(flash.alert).to eq(['Le champ l doit être rempli.', 'pj']) }
context 'and the user saves a draft' do
let(:payload) { submit_payload.merge(submit_action: 'draft') }
it { expect(response).to render_template(:modifier) }
it { expect(flash.notice).to eq('Votre brouillon a bien été sauvegardé.') }
it { expect(dossier.reload.state).to eq('brouillon') }
end
end
end
end end

View file

@ -59,21 +59,14 @@ shared_examples 'carte_controller_spec' do
end end
describe 'POST #save' do describe 'POST #save' do
context 'Aucune localisation n\'a jamais été enregistrée' do
it do
post :save, params: { dossier_id: dossier.id, json_latlngs: '' }
expect(response).to redirect_to("/users/dossiers/#{dossier.id}/description")
end
end
context 'En train de modifier la localisation' do context 'En train de modifier la localisation' do
let(:dossier) { create(:dossier, state: 'en_construction') } let(:dossier) { create(:dossier, state: 'en_construction') }
before do before do
post :save, params: { dossier_id: dossier.id, json_latlngs: '' } post :save, params: { dossier_id: dossier.id, json_latlngs: '' }
end end
it 'Redirection vers la page récapitulatif' do it 'Redirection vers le formulaire de la procedure' do
expect(response).to redirect_to("/users/dossiers/#{dossier.id}/recapitulatif") expect(response).to redirect_to(modifier_dossier_path(dossier))
end end
end end

View file

@ -398,7 +398,7 @@ describe Users::DossiersController, type: :controller do
context 'procedure not use api carto' do context 'procedure not use api carto' do
it 'redirects to demande' do it 'redirects to demande' do
expect(response).to redirect_to(controller: :description, action: :show, dossier_id: dossier.id) expect(response).to redirect_to(modifier_dossier_path(dossier))
end end
end end

View file

@ -52,30 +52,4 @@ describe DossierDecorator do
expect(subject).to eq('Refusé') expect(subject).to eq('Refusé')
end end
end end
describe '#url' do
context "when a gestionnaire is not signed_in" do
context "when the dossier is in brouillon state" do
before do
dossier.state = 'brouillon'
dossier.save
end
subject { super().url(false) }
it { is_expected.to eq("/users/dossiers/#{dossier.id}/description") }
end
context "when the dossier is not in brouillon state" do
before do
dossier.state = 'en_construction'
dossier.save
end
subject { super().url(false) }
it { is_expected.to eq("/users/dossiers/#{dossier.id}/recapitulatif") }
end
end
end
end end

View file

@ -110,5 +110,33 @@ FactoryBot.define do
procedure.archived_at = Time.now procedure.archived_at = Time.now
end end
end end
trait :with_all_champs_mandatory do
after(:build) do |procedure, _evaluator|
tdcs = []
tdcs << create(:type_de_champ, type_champ: 'text', mandatory: true, libelle: 'text')
tdcs << create(:type_de_champ, type_champ: 'textarea', mandatory: true, libelle: 'textarea')
tdcs << create(:type_de_champ, type_champ: 'date', mandatory: true, libelle: 'date')
tdcs << create(:type_de_champ, type_champ: 'datetime', mandatory: true, libelle: 'datetime')
tdcs << create(:type_de_champ, type_champ: 'number', mandatory: true, libelle: 'number')
tdcs << create(:type_de_champ, type_champ: 'checkbox', mandatory: true, libelle: 'checkbox')
tdcs << create(:type_de_champ, type_champ: 'civilite', mandatory: true, libelle: 'civilite')
tdcs << create(:type_de_champ, type_champ: 'email', mandatory: true, libelle: 'email')
tdcs << create(:type_de_champ, type_champ: 'phone', mandatory: true, libelle: 'phone')
tdcs << create(:type_de_champ, type_champ: 'yes_no', mandatory: true, libelle: 'yes_no')
tdcs << create(:type_de_champ, :type_drop_down_list, mandatory: true, libelle: 'simple_drop_down_list')
tdcs << create(:type_de_champ, :type_drop_down_list, type_champ: 'multiple_drop_down_list', mandatory: true, libelle: 'multiple_drop_down_list')
tdcs << create(:type_de_champ, type_champ: 'pays', mandatory: true, libelle: 'pays')
tdcs << create(:type_de_champ, type_champ: 'regions', mandatory: true, libelle: 'regions')
tdcs << create(:type_de_champ, type_champ: 'departements', mandatory: true, libelle: 'departements')
tdcs << create(:type_de_champ, type_champ: 'engagement', mandatory: true, libelle: 'engagement')
tdcs << create(:type_de_champ, type_champ: 'header_section', mandatory: true, libelle: 'header_section')
tdcs << create(:type_de_champ, type_champ: 'explication', mandatory: true, libelle: 'explication')
tdcs << create(:type_de_champ, :type_dossier_link, mandatory: true, libelle: 'dossier_link')
tdcs << create(:type_de_champ, type_champ: 'piece_justificative', mandatory: true, libelle: 'piece_justificative')
procedure.types_de_champ = tdcs
end
end
end end
end end

View file

@ -0,0 +1,155 @@
require 'spec_helper'
feature 'The user' do
let(:password) { 'secret_password' }
let!(:user) { create(:user, password: password) }
let!(:procedure) { create(:procedure, :published, :for_individual, :with_all_champs_mandatory) }
let(:user_dossier) { user.dossiers.first }
# TODO: check
# the order
# there are no extraneous input
# attached file works
scenario 'fill a dossier', js: true do
allow(Champ).to receive(:regions).and_return(['region1', 'region2']).at_least(:once)
allow(Champ).to receive(:departements).and_return(['dep1', 'dep2']).at_least(:once)
log_in(user.email, password, procedure)
fill_individual
# fill data
fill_in('text', with: 'super texte')
fill_in('textarea', with: 'super textarea')
fill_in('date', with: '12/12/2012')
select_date_and_time(DateTime.parse('06/01/1985 7h05'), form_id_for('datetime'))
fill_in('number', with: '42')
check('checkbox')
choose('Madame')
fill_in('email', with: 'loulou@yopmail.com')
fill_in('phone', with: '1234567890')
choose('Non')
select('val2', from: form_id_for('simple_drop_down_list'))
select('val1', from: form_id_for('multiple_drop_down_list'))
select('val3', from: form_id_for('multiple_drop_down_list'))
select('AUSTRALIE', from: 'pays')
select('region2', from: 'regions')
select('dep2', from: 'departements')
check('engagement')
fill_in('dossier_link', with: '123')
# do not know how to make it work...
# find('form input[type="file"]').set(Rails.root.join('spec/fixtures/white.png'))
click_on 'Enregistrer le brouillon'
# 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('06/01/1985 07:05')
expect(champ_value_for('number')).to eq('42')
expect(champ_value_for('checkbox')).to eq('on')
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('1234567890')
expect(champ_value_for('yes_no')).to eq('false')
expect(champ_value_for('simple_drop_down_list')).to eq('val2')
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('region2')
expect(champ_value_for('departements')).to eq('dep2')
expect(champ_value_for('engagement')).to eq('on')
expect(champ_value_for('dossier_link')).to eq('123')
## check data on the gui
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')
check_date_and_time(DateTime.parse('06/01/1985 7:05'), form_id_for('datetime'))
expect(page).to have_field('number', with: '42')
expect(page).to have_checked_field('checkbox')
expect(page).to have_checked_field('Madame')
expect(page).to have_field('email', with: 'loulou@yopmail.com')
expect(page).to have_field('phone', with: '1234567890')
expect(page).to have_checked_field('Non')
expect(page).to have_select('simple_drop_down_list', selected: 'val2')
expect(page).to have_select('multiple_drop_down_list', selected: ['val1', 'val3'])
expect(page).to have_select('pays', selected: 'AUSTRALIE')
expect(page).to have_select('regions', selected: 'region2')
expect(page).to have_select('departement', selected: 'dep2')
expect(page).to have_checked_field('engagement')
expect(page).to have_field('dossier_link', with: '123')
end
let(:simple_procedure) do
tdcs = [create(:type_de_champ, type_champ: 'text', mandatory: true, libelle: 'text')]
create(:procedure, :published, :for_individual, types_de_champ: tdcs)
end
scenario 'save an incomplete dossier as draft but cannot not submit it', js: true do
log_in(user.email, password, simple_procedure)
fill_individual
click_on 'Enregistrer le brouillon'
expect(page).to have_content('Votre brouillon a bien été sauvegardé')
expect(page).to have_current_path(dossier_path(user_dossier))
click_on 'Soumettre le dossier'
expect(user_dossier.reload.brouillon?).to be(true)
expect(page).to have_current_path(dossier_path(user_dossier))
fill_in('text', with: 'super texte')
click_on 'Soumettre le dossier'
expect(user_dossier.reload.en_construction?).to be(true)
expect(champ_value_for('text')).to eq('super texte')
expect(page).to have_current_path(users_dossier_recapitulatif_path(user_dossier))
end
private
def log_in(email, password, procedure)
visit "/commencer/#{procedure.procedure_path.path}"
expect(page).to have_current_path(new_user_session_path)
fill_in 'user_email', with: email
fill_in 'user_password', with: password
click_on 'Se connecter'
expect(page).to have_current_path(identite_dossier_path(user_dossier))
end
def form_id_for(libelle)
find(:xpath, ".//label[contains(text()[normalize-space()], '#{libelle}')]")[:for]
end
def champ_value_for(libelle)
champs = user_dossier.champs
champs.find { |c| c.libelle == libelle }.value
end
def fill_individual
fill_in('individual_prenom', with: 'prenom')
fill_in('individual_nom', with: 'nom')
check 'dossier_autorisation_donnees'
click_on 'Continuer'
expect(page).to have_current_path(modifier_dossier_path(user_dossier))
end
def select_date_and_time(date, field)
select date.strftime('%Y'), from: "#{field}_1i" # year
select I18n.l(date, format: '%B'), from: "#{field}_2i" # month
select date.strftime('%-d'), from: "#{field}_3i" # day
select date.strftime('%H'), from: "#{field}_4i" # hour
select date.strftime('%M'), from: "#{field}_5i" # minute
end
def check_date_and_time(date, field)
expect(page).to have_select("#{field}_1i", selected: date.strftime('%Y'))
expect(page).to have_select("#{field}_2i", selected: I18n.l(date, format: '%B'))
expect(page).to have_select("#{field}_3i", selected: date.strftime('%-d'))
expect(page).to have_select("#{field}_4i", selected: date.strftime('%H'))
expect(page).to have_select("#{field}_5i", selected: date.strftime('%M'))
end
end

View file

@ -63,13 +63,13 @@ feature 'user path for dossier creation' do
page.check('dossier_autorisation_donnees') page.check('dossier_autorisation_donnees')
page.find_by_id('etape_suivante').click page.find_by_id('etape_suivante').click
end end
scenario 'user is on description page' do scenario 'user is on edition page' do
expect(page).to have_css('#description-page') expect(page).to have_current_path(modifier_dossier_path(Dossier.last))
end end
context 'user fill and validate description page' do context 'user fill and validate description page' do
before do before do
page.find_by_id("champs_#{Dossier.last.champs.first.id}").set 'Mon super projet' page.find_by_id("dossier_champs_attributes_0_value").set 'Mon super projet'
page.find_by_id('suivant').click click_on 'Soumettre le dossier'
end end
scenario 'user is on recap page' do scenario 'user is on recap page' do
expect(page).to have_css('#users-recapitulatif-dossier-show') expect(page).to have_css('#users-recapitulatif-dossier-show')

View file

@ -28,13 +28,9 @@ feature 'As a User I wanna create a dossier' do
expect(page).to have_current_path(users_dossier_carte_path(procedure_for_individual.dossiers.last.id)) expect(page).to have_current_path(users_dossier_carte_path(procedure_for_individual.dossiers.last.id))
click_button('Etape suivante') click_button('Etape suivante')
expect(page).to have_current_path(users_dossier_description_path(procedure_for_individual.dossiers.last.id)) expect(page).to have_current_path(modifier_dossier_path(procedure_for_individual.dossiers.last))
fill_in "champs_#{procedure_for_individual.dossiers.last.champs.first.id}", with: 'contenu du champ 1'
find(:css, '[name=submit_action]').set('nouveaux')
click_button('suivant')
expect(user.dossiers.first.individual.birthdate).to eq("1987-10-14") expect(user.dossiers.first.individual.birthdate).to eq("1987-10-14")
expect(page).to have_current_path(users_dossier_recapitulatif_path(procedure_for_individual.dossiers.last.id.to_s))
end end
scenario "with a basic text input field for birthdate (type='date' unsupported)" do scenario "with a basic text input field for birthdate (type='date' unsupported)" do
@ -44,12 +40,9 @@ feature 'As a User I wanna create a dossier' do
expect(page).to have_current_path(users_dossier_carte_path(procedure_for_individual.dossiers.last.id.to_s)) expect(page).to have_current_path(users_dossier_carte_path(procedure_for_individual.dossiers.last.id.to_s))
click_button('Etape suivante') click_button('Etape suivante')
fill_in "champs_#{procedure_for_individual.dossiers.last.champs.first.id}", with: 'contenu du champ 1' expect(page).to have_current_path(modifier_dossier_path(procedure_for_individual.dossiers.last))
find(:css, '[name=submit_action]').set('nouveaux')
page.find_by_id('suivant').click
expect(user.dossiers.first.individual.birthdate).to eq("1987-10-14") expect(user.dossiers.first.individual.birthdate).to eq("1987-10-14")
expect(page).to have_current_path(users_dossier_recapitulatif_path(procedure_for_individual.dossiers.last.id.to_s))
end end
end end
@ -59,15 +52,12 @@ feature 'As a User I wanna create a dossier' do
scenario "no need for birthday" do scenario "no need for birthday" do
click_button('Continuer') click_button('Continuer')
expect(page).to have_current_path(users_dossier_carte_path(procedure_for_individual.dossiers.last.id.to_s)) expect(page).to have_current_path(users_dossier_carte_path(procedure_for_individual.dossiers.last))
click_button('Etape suivante') click_button('Etape suivante')
fill_in "champs_#{procedure_for_individual.dossiers.last.champs.first.id}", with: 'contenu du champ 1' expect(page).to have_current_path(modifier_dossier_path(procedure_for_individual.dossiers.last))
find(:css, '[name=submit_action]').set('nouveaux')
click_button('suivant')
expect(user.dossiers.first.individual.birthdate).to eq(nil) expect(user.dossiers.first.individual.birthdate).to eq(nil)
expect(page).to have_current_path(users_dossier_recapitulatif_path(procedure_for_individual.dossiers.last.id.to_s))
end end
end end
end end
@ -92,9 +82,7 @@ feature 'As a User I wanna create a dossier' do
page.find_by_id('etape_suivante').click page.find_by_id('etape_suivante').click
expect(page).to have_current_path(users_dossier_carte_path(procedure_with_siret.dossiers.last.id.to_s)) expect(page).to have_current_path(users_dossier_carte_path(procedure_with_siret.dossiers.last.id.to_s))
page.find_by_id('etape_suivante').click page.find_by_id('etape_suivante').click
fill_in "champs_#{procedure_with_siret.dossiers.last.champs.first.id}", with: 'contenu du champ 1' expect(page).to have_current_path(modifier_dossier_path(procedure_with_siret.dossiers.last))
page.find_by_id('suivant').click
expect(page).to have_current_path(users_dossier_recapitulatif_path(procedure_with_siret.dossiers.last.id.to_s))
end end
end end
end end

View file

@ -1,49 +0,0 @@
require 'spec_helper'
feature 'As a User I want to edit a dossier I own' do
let(:user) { create(:user) }
let(:procedure_for_individual) { create(:procedure, :published, :for_individual, :with_type_de_champ, :with_two_type_de_piece_justificative, :with_dossier_link) }
let!(:dossier) { create(:dossier, :with_entreprise, :for_individual, :with_dossier_link, procedure: procedure_for_individual, user: user, autorisation_donnees: true, state: 'en_construction') }
before "Create dossier and visit root path" do
login_as user, scope: :user
visit root_path
end
context 'After sign_in, I can navigate through dossiers indexes and edit a dossier' do
scenario 'After sign_in, I can see dossiers "à traiter" (default), and other indexes' do
expect(page.find('#a_traiter')['class']).to eq('active procedure-list-element')
page.find_by_id('brouillon').click
page.find_by_id('a_traiter').click
page.find_by_id('en_instruction').click
page.find_by_id('termine').click
page.find_by_id('invite').click
end
scenario 'Getting a dossier, I want to create a new message on', js: true do
page.find_by_id("tr_dossier_#{dossier.id.to_s}").click
expect(page).to have_current_path(users_dossier_recapitulatif_path(Dossier.first.id.to_s))
page.find_by_id('open-message').click
page.execute_script("$('#texte_commentaire').data('wysihtml5').editor.setValue('Contenu du nouveau message')")
page.find_by_id('save-message').click
expect(page.find('.last-commentaire .content').text).to eq('Contenu du nouveau message')
end
scenario 'On the same dossier, I want to edit informations', js: true do
page.find_by_id("tr_dossier_#{dossier.id.to_s}").click
expect(page).to have_current_path(users_dossier_recapitulatif_path(dossier.id.to_s))
# Linked Dossier
linked_dossier_id = dossier.champs.find { |c| c.type_de_champ.type_champ == 'dossier_link' }.value
expect(page).to have_link("Dossier #{linked_dossier_id}")
page.find_by_id('edit-dossier').click
expect(page).to have_current_path(users_dossier_description_path(dossier.id.to_s))
champ_id = dossier.champs.find { |t| t.type_champ == "text" }.id
fill_in "champs_#{champ_id.to_s}", with: 'Contenu du champ 1'
page.find_by_id('modification_terminee').click
expect(page).to have_current_path(users_dossier_recapitulatif_path(dossier.id.to_s))
expect(page.find("#champ-#{champ_id}-value").text).to eq('Contenu du champ 1')
end
end
end

View file

@ -30,8 +30,8 @@ describe 'users/recapitulatif/show.html.haml', type: :view do
expect(rendered).to have_css('#maj_infos') expect(rendered).to have_css('#maj_infos')
end end
it 'le lien vers description est correct' do it 'le lien vers l édition est correct' do
expect(rendered).to have_selector("a[id=maj_infos][href='/users/dossiers/#{dossier_id}/description']") expect(rendered).to have_selector("a[id=maj_infos][href='/dossiers/#{dossier_id}/modifier']")
end end
end end