feat(demarche): sign up when prefilling a dossier (#8247)
* store prefill params in session Instead of using query params on /dossier/new, we assume the user comes from /commencer/:path, which is the new prefill link. There, we store the prefill params in session, and use them to prefill the dossier when creating it, in /dossiers/new. * spec: cover the case * review: serialize with json instead of yaml * review: rename method * review: store only query params * review: comment why we dont override already stored params
This commit is contained in:
parent
663c13f819
commit
b8ff0ba4a2
9 changed files with 141 additions and 30 deletions
17
app/controllers/concerns/query_params_store_concern.rb
Normal file
17
app/controllers/concerns/query_params_store_concern.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
module QueryParamsStoreConcern
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
def store_query_params
|
||||||
|
# Don't override already stored params, because we could do goings and comings with authentication, and
|
||||||
|
# lost previously stored params
|
||||||
|
return if session[:stored_params].present? || request.query_parameters.empty?
|
||||||
|
|
||||||
|
session[:stored_params] = request.query_parameters.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
def retrieve_and_delete_stored_query_params
|
||||||
|
return {} if session[:stored_params].blank?
|
||||||
|
|
||||||
|
JSON.parse(session.delete(:stored_params))
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,11 +1,15 @@
|
||||||
module Users
|
module Users
|
||||||
class CommencerController < ApplicationController
|
class CommencerController < ApplicationController
|
||||||
|
include QueryParamsStoreConcern
|
||||||
|
|
||||||
layout 'procedure_context'
|
layout 'procedure_context'
|
||||||
|
|
||||||
def commencer
|
def commencer
|
||||||
@procedure = retrieve_procedure
|
@procedure = retrieve_procedure
|
||||||
return procedure_not_found if @procedure.blank? || @procedure.brouillon?
|
return procedure_not_found if @procedure.blank? || @procedure.brouillon?
|
||||||
|
|
||||||
|
store_query_params
|
||||||
|
|
||||||
@revision = @procedure.published_revision
|
@revision = @procedure.published_revision
|
||||||
render 'commencer/show'
|
render 'commencer/show'
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
module Users
|
module Users
|
||||||
class DossiersController < UserController
|
class DossiersController < UserController
|
||||||
include DossierHelper
|
include DossierHelper
|
||||||
|
include QueryParamsStoreConcern
|
||||||
|
|
||||||
layout 'procedure_context', only: [:identite, :update_identite, :siret, :update_siret]
|
layout 'procedure_context', only: [:identite, :update_identite, :siret, :update_siret]
|
||||||
|
|
||||||
|
@ -304,7 +305,7 @@ module Users
|
||||||
)
|
)
|
||||||
dossier.build_default_individual
|
dossier.build_default_individual
|
||||||
dossier.save!
|
dossier.save!
|
||||||
dossier.prefill!(PrefillParams.new(dossier, params).to_a)
|
dossier.prefill!(PrefillParams.new(dossier, retrieve_and_delete_stored_query_params).to_a)
|
||||||
|
|
||||||
if dossier.procedure.for_individual
|
if dossier.procedure.for_individual
|
||||||
redirect_to identite_dossier_path(dossier)
|
redirect_to identite_dossier_path(dossier)
|
||||||
|
|
|
@ -12,7 +12,6 @@ class PrefillParams
|
||||||
|
|
||||||
def build_prefill_values
|
def build_prefill_values
|
||||||
value_by_stable_id = @params
|
value_by_stable_id = @params
|
||||||
.to_unsafe_hash
|
|
||||||
.map { |prefixed_typed_id, value| [stable_id_from_typed_id(prefixed_typed_id), value] }
|
.map { |prefixed_typed_id, value| [stable_id_from_typed_id(prefixed_typed_id), value] }
|
||||||
.filter { |stable_id, value| stable_id.present? && value.present? }
|
.filter { |stable_id, value| stable_id.present? && value.present? }
|
||||||
.to_h
|
.to_h
|
||||||
|
|
66
spec/controllers/concerns/query_params_store_concern_spec.rb
Normal file
66
spec/controllers/concerns/query_params_store_concern_spec.rb
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
RSpec.describe QueryParamsStoreConcern, type: :controller do
|
||||||
|
class TestController < ActionController::Base
|
||||||
|
include QueryParamsStoreConcern
|
||||||
|
end
|
||||||
|
|
||||||
|
controller TestController do
|
||||||
|
end
|
||||||
|
|
||||||
|
before { allow_any_instance_of(ActionDispatch::Request).to receive(:query_parameters).and_return(params) }
|
||||||
|
|
||||||
|
describe '#store_query_params' do
|
||||||
|
subject(:store_query_params) { controller.store_query_params }
|
||||||
|
|
||||||
|
context 'when params are already stored' do
|
||||||
|
let(:params) { { param1: "param1" } }
|
||||||
|
|
||||||
|
it "does nothing" do
|
||||||
|
session[:stored_params] = "there is alread something in there"
|
||||||
|
|
||||||
|
expect { store_query_params }.not_to change { session[:stored_params] }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when params are empty' do
|
||||||
|
let(:params) { {} }
|
||||||
|
|
||||||
|
it "does nothing" do
|
||||||
|
expect { store_query_params }.not_to change { session[:stored_params] }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the store is empty and we have params' do
|
||||||
|
let(:params) { { param1: "param1", param2: "param2" } }
|
||||||
|
|
||||||
|
it "stores the query params" do
|
||||||
|
expect { store_query_params }.to change { session[:stored_params] }.from(nil).to(params.to_json)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#retrieve_and_delete_stored_query_params' do
|
||||||
|
subject(:retrieve_and_delete_stored_query_params) { controller.retrieve_and_delete_stored_query_params }
|
||||||
|
|
||||||
|
context 'when there are no stored params' do
|
||||||
|
let(:params) { {} }
|
||||||
|
|
||||||
|
it 'returns an empty hash' do
|
||||||
|
expect(retrieve_and_delete_stored_query_params).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when params are stored' do
|
||||||
|
let(:params) { { param1: "param1", param2: "param2" } }
|
||||||
|
|
||||||
|
before { controller.store_query_params }
|
||||||
|
|
||||||
|
it 'deletes the stored params' do
|
||||||
|
expect { retrieve_and_delete_stored_query_params }.to change { session[:stored_params] }.to(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the stored params' do
|
||||||
|
expect(retrieve_and_delete_stored_query_params).to match(params.with_indifferent_access)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -15,6 +15,16 @@ describe Users::CommencerController, type: :controller do
|
||||||
expect(assigns(:procedure)).to eq published_procedure
|
expect(assigns(:procedure)).to eq published_procedure
|
||||||
expect(assigns(:revision)).to eq published_procedure.published_revision
|
expect(assigns(:revision)).to eq published_procedure.published_revision
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when there are query params' do
|
||||||
|
subject { get :commencer, params: { path: path, any_param: "any param" } }
|
||||||
|
|
||||||
|
it "stores the parameters in session" do
|
||||||
|
subject
|
||||||
|
|
||||||
|
expect(session[:stored_params]).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the path is for a draft procedure' do
|
context 'when the path is for a draft procedure' do
|
||||||
|
|
|
@ -1067,7 +1067,7 @@ describe Users::DossiersController, type: :controller do
|
||||||
it { is_expected.to redirect_to dossiers_path }
|
it { is_expected.to redirect_to dossiers_path }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when prefill values are given' do
|
context 'when prefill values have been stored in session before' do
|
||||||
let!(:type_de_champ_1) { create(:type_de_champ_text, procedure: procedure) }
|
let!(:type_de_champ_1) { create(:type_de_champ_text, procedure: procedure) }
|
||||||
let(:value_1) { "any value" }
|
let(:value_1) { "any value" }
|
||||||
|
|
||||||
|
@ -1082,6 +1082,10 @@ describe Users::DossiersController, type: :controller do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
before { session[:stored_params] = params.to_json }
|
||||||
|
|
||||||
|
it { expect { subject }.to change { session[:stored_params] }.to(nil) }
|
||||||
|
|
||||||
it { expect { subject }.to change { Dossier.count }.by(1) }
|
it { expect { subject }.to change { Dossier.count }.by(1) }
|
||||||
|
|
||||||
it "prefills the dossier's champs with the given values" do
|
it "prefills the dossier's champs with the given values" do
|
||||||
|
|
|
@ -3,7 +3,7 @@ RSpec.describe PrefillParams do
|
||||||
let(:procedure) { create(:procedure, :published) }
|
let(:procedure) { create(:procedure, :published) }
|
||||||
let(:dossier) { create(:dossier, :brouillon, procedure: procedure) }
|
let(:dossier) { create(:dossier, :brouillon, procedure: procedure) }
|
||||||
|
|
||||||
subject(:prefill_params_array) { described_class.new(dossier, ActionController::Parameters.new(params)).to_a }
|
subject(:prefill_params_array) { described_class.new(dossier, params).to_a }
|
||||||
|
|
||||||
context "when the stable ids match the TypeDeChamp of the corresponding procedure" do
|
context "when the stable ids match the TypeDeChamp of the corresponding procedure" do
|
||||||
let!(:type_de_champ_1) { create(:type_de_champ_text, procedure: procedure) }
|
let!(:type_de_champ_1) { create(:type_de_champ_text, procedure: procedure) }
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
describe 'Prefilling a dossier:' do
|
describe 'Prefilling a dossier:' do
|
||||||
|
let(:password) { 'my-s3cure-p4ssword' }
|
||||||
let(:siret) { '41816609600051' }
|
let(:siret) { '41816609600051' }
|
||||||
|
|
||||||
let(:procedure) { create(:procedure, :published, opendata: true) }
|
let(:procedure) { create(:procedure, :published, opendata: true) }
|
||||||
|
@ -13,20 +14,16 @@ describe 'Prefilling a dossier:' do
|
||||||
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}/)
|
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}/)
|
||||||
.to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/etablissements.json'))
|
.to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/etablissements.json'))
|
||||||
|
|
||||||
visit new_dossier_path(
|
visit commencer_path(
|
||||||
procedure_id: procedure.id,
|
path: procedure.path,
|
||||||
"champ_#{type_de_champ_text.to_typed_id}" => text_value,
|
"champ_#{type_de_champ_text.to_typed_id}" => text_value,
|
||||||
"champ_#{type_de_champ_phone.to_typed_id}" => phone_value
|
"champ_#{type_de_champ_phone.to_typed_id}" => phone_value
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the user already exists' do
|
shared_examples "the user has got a prefilled dossier" do
|
||||||
let(:password) { 'my-s3cure-p4ssword' }
|
scenario "the user has got a prefilled dossier" do
|
||||||
let!(:user) { create(:user, password: password) }
|
click_on "Commencer la démarche"
|
||||||
|
|
||||||
scenario "the user has got a prefilled dossier after signing in" do
|
|
||||||
expect(page).to have_content("Connectez-vous")
|
|
||||||
sign_in_with user.email, password
|
|
||||||
|
|
||||||
expect(page).to have_current_path siret_dossier_path(procedure.dossiers.last)
|
expect(page).to have_current_path siret_dossier_path(procedure.dossiers.last)
|
||||||
fill_in 'Numéro SIRET', with: siret
|
fill_in 'Numéro SIRET', with: siret
|
||||||
|
@ -43,28 +40,41 @@ describe 'Prefilling a dossier:' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when this is a new user' do
|
context 'when the user signs in with email and password' do
|
||||||
before do
|
it_behaves_like "the user has got a prefilled dossier" do
|
||||||
allow_any_instance_of(FranceConnectParticulierClient).to receive(:authorization_uri).and_return(france_connect_particulier_callback_path(code: "c0d3"))
|
let!(:user) { create(:user, password: password) }
|
||||||
allow(FranceConnectService).to receive(:retrieve_user_informations_particulier).and_return(build(:france_connect_information))
|
|
||||||
|
before do
|
||||||
|
click_on "J’ai déjà un compte"
|
||||||
|
sign_in_with user.email, password
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
scenario "the user has got a prefilled dossier after signing up" do
|
context 'when the user signs up with email and password' do
|
||||||
expect(page).to have_content("Connectez-vous")
|
it_behaves_like "the user has got a prefilled dossier" do
|
||||||
page.find('.fr-connect').click
|
let(:user_email) { generate :user_email }
|
||||||
|
|
||||||
expect(page).to have_current_path siret_dossier_path(procedure.dossiers.last)
|
before do
|
||||||
fill_in 'Numéro SIRET', with: siret
|
click_on "Créer un compte #{APPLICATION_NAME}"
|
||||||
click_on 'Valider'
|
|
||||||
|
|
||||||
expect(page).to have_current_path(etablissement_dossier_path(dossier))
|
sign_up_with user_email, password
|
||||||
expect(page).to have_content('OCTO TECHNOLOGY')
|
expect(page).to have_content "nous avons besoin de vérifier votre adresse #{user_email}"
|
||||||
click_on 'Continuer avec ces informations'
|
|
||||||
|
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
click_confirmation_link_for user_email
|
||||||
expect(page).to have_field(type_de_champ_text.libelle, with: text_value)
|
expect(page).to have_content('Votre compte a bien été confirmé.')
|
||||||
expect(page).to have_field(type_de_champ_phone.libelle, with: phone_value)
|
end
|
||||||
expect(page).to have_css('.field_with_errors', text: type_de_champ_phone.libelle)
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the user signs up with FranceConnect' do
|
||||||
|
it_behaves_like "the user has got a prefilled dossier" do
|
||||||
|
before do
|
||||||
|
allow_any_instance_of(FranceConnectParticulierClient).to receive(:authorization_uri).and_return(france_connect_particulier_callback_path(code: "c0d3"))
|
||||||
|
allow(FranceConnectService).to receive(:retrieve_user_informations_particulier).and_return(build(:france_connect_information))
|
||||||
|
|
||||||
|
page.find('.fr-connect').click
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue