Merge pull request #3290 from betagouv/sign-up-procedure-context

[Page de garde] Ajout du contexte de la démarche sur la page de sign-up
This commit is contained in:
Pierre de La Morinerie 2019-01-17 11:20:21 +01:00 committed by GitHub
commit 8d70a67bc2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 246 additions and 78 deletions

View file

@ -0,0 +1,34 @@
module ProcedureContextConcern
extend ActiveSupport::Concern
include Devise::Controllers::StoreLocation
include Devise::StoreLocationExtension
def restore_procedure_context
if stored_procedure_id.present?
@procedure = Procedure.publiees.find_by(id: stored_procedure_id)
if @procedure.blank?
invalid_procedure_context
end
end
end
private
def stored_procedure_id
stored_location = get_stored_location_for(:user)
if stored_location.present? && stored_location.include?('procedure_id=')
stored_location.split('procedure_id=').second
else
nil
end
end
def invalid_procedure_context
clear_stored_location_for(:user)
flash.alert = t('errors.messages.procedure_not_found')
redirect_to root_path
end
end

View file

@ -0,0 +1,19 @@
module Devise
# Useful helpers additions to Devise::Controllers::StoreLocation
module StoreLocationExtension
# A variant of `stored_location_key_for` which doesn't delete the stored path.
def get_stored_location_for(resource_or_scope)
location = stored_location_for(resource_or_scope)
if location
store_location_for(resource_or_scope, location)
end
location
end
# Delete the url stored in the session for the given scope.
def clear_stored_location_for(resource_or_scope)
session_key = send(:stored_location_key_for, resource_or_scope)
session.delete(session_key)
end
end
end

View file

@ -1,5 +1,5 @@
class InvitesController < ApplicationController
SESSION_USER_RETURN_LOCATION = 'user_return_to'
include Devise::StoreLocationExtension
before_action :authenticate_user!, only: [:create]
before_action :store_user_location!, only: [:show]
@ -62,6 +62,6 @@ class InvitesController < ApplicationController
end
def erase_user_location!
session.delete(SESSION_USER_RETURN_LOCATION)
clear_stored_location_for(:user)
end
end

View file

@ -1,10 +1,10 @@
module NewUser
class DossiersController < UserController
include Devise::StoreLocationExtension
include DossierHelper
layout 'procedure_context', only: [:identite, :update_identite, :siret, :update_siret]
SESSION_USER_RETURN_LOCATION = 'user_return_to'
ACTIONS_ALLOWED_TO_ANY_USER = [:index, :recherche, :new]
ACTIONS_ALLOWED_TO_OWNER_OR_INVITE = [:show, :demande, :messagerie, :brouillon, :update_brouillon, :modifier, :update, :create_commentaire, :purge_champ_piece_justificative]
@ -247,7 +247,7 @@ module NewUser
end
def erase_user_location!
session.delete(SESSION_USER_RETURN_LOCATION)
clear_stored_location_for(:user)
end
def show_demarche_en_test_banner

View file

@ -1,10 +1,9 @@
class Users::RegistrationsController < Devise::RegistrationsController
include ProcedureContextConcern
# before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]
# def after_sign_up_path_for(resource_or_scope)
# super
# end
before_action :restore_procedure_context, only: [:new, :create]
layout 'procedure_context', only: [:new, :create]

View file

@ -1,18 +1,15 @@
class Users::SessionsController < Sessions::SessionsController
include ProcedureContextConcern
include TrustedDeviceConcern
include ActionView::Helpers::DateHelper
layout 'procedure_context', only: [:new, :create]
before_action :restore_procedure_context, only: [:new, :create]
# GET /resource/sign_in
def new
if user_return_to_procedure_id.present?
@procedure = Procedure.active(user_return_to_procedure_id)
end
@user = User.new
rescue ActiveRecord::RecordNotFound
error_procedure
end
# POST /resource/sign_in
@ -80,7 +77,7 @@ class Users::SessionsController < Sessions::SessionsController
end
def no_procedure
session['user_return_to'] = nil
clear_stored_location_for(:user)
redirect_to new_user_session_path
end
@ -112,20 +109,6 @@ class Users::SessionsController < Sessions::SessionsController
end
end
def error_procedure
session["user_return_to"] = nil
flash.alert = t('errors.messages.procedure_not_found')
redirect_to url_for root_path
end
def user_return_to_procedure_id
if session["user_return_to"].nil?
return nil
end
NumberService.to_number session["user_return_to"].split("?procedure_id=").second
end
def try_to_authenticate(klass, remember_me = false)
resource = klass.find_for_database_authentication(email: params[:user][:email])

View file

@ -1,5 +0,0 @@
class NumberService
def self.to_number(string)
string.to_s
end
end

View file

@ -0,0 +1,77 @@
require 'rails_helper'
RSpec.describe ProcedureContextConcern, type: :controller do
class TestController < ActionController::Base
include ProcedureContextConcern
before_action :restore_procedure_context
def index
head :ok
end
end
controller TestController do
end
describe '#restore_procedure_context' do
subject { get :index }
context 'when no return location has been stored' do
it 'succeeds, without defining a procedure on the controller' do
expect(subject.status).to eq 200
expect(assigns(:procedure)).to be nil
end
end
context 'when no procedure_id is present in the stored return location' do
before do
controller.store_location_for(:user, dossiers_path)
end
it 'succeeds, without assigns a procedure on the controller' do
expect(subject.status).to eq 200
expect(assigns(:procedure)).to be nil
end
end
context 'when a procedure location has been stored' do
context 'when the stored procedure does not exist' do
before do
controller.store_location_for(:user, new_dossier_path(procedure_id: '0'))
end
it 'redirects with an error' do
expect(subject.status).to eq 302
expect(subject).to redirect_to root_path
end
end
context 'when the stored procedure is not published' do
let(:procedure) { create :procedure }
before do
controller.store_location_for(:user, new_dossier_path(procedure_id: procedure.id))
end
it 'redirects with an error' do
expect(subject.status).to eq 302
expect(subject).to redirect_to root_path
end
end
context 'when the stored procedure exists' do
let(:procedure) { create :procedure, :published }
before do
controller.store_location_for(:user, new_dossier_path(procedure_id: procedure.id))
end
it 'succeeds, and assigns the procedure on the controller' do
expect(subject.status).to eq 200
expect(assigns(:procedure)).to eq procedure
end
end
end
end
end

View file

@ -0,0 +1,41 @@
require 'rails_helper'
RSpec.describe Devise::StoreLocationExtension, type: :controller do
class TestController < ActionController::Base
include Devise::Controllers::StoreLocation
include Devise::StoreLocationExtension
end
controller TestController do
end
describe '#get_stored_location_for' do
context 'when a location has been previously stored' do
before { subject.store_location_for(:user, dossiers_path) }
it 'returns the stored location without clearing it' do
expect(subject.get_stored_location_for(:user)).to eq dossiers_path
expect(subject.stored_location_for(:user)).to eq dossiers_path
end
end
context 'when no location has been stored' do
it { expect(subject.get_stored_location_for(:user)).to be nil }
end
end
describe "#clear_stored_location_for" do
context 'when a location has been previously stored' do
before { subject.store_location_for(:user, dossiers_path) }
it 'delete the stored location' do
subject.clear_stored_location_for(:user)
expect(subject.stored_location_for(:user)).to be nil
end
end
context 'when no location has been stored' do
it { expect(subject.clear_stored_location_for(:user)).to be nil }
end
end
end

View file

@ -171,7 +171,10 @@ describe InvitesController, type: :controller do
let(:email) { nil }
context 'and user is not connected' do
it { is_expected.to redirect_to new_user_session_path }
it 'redirects to the sign-in page' do
expect(subject).to redirect_to new_user_session_path
expect(controller.stored_location_for(:user)).to be_present
end
end
context 'and user is connected' do
@ -186,20 +189,29 @@ describe InvitesController, type: :controller do
context 'when email is blank' do
let(:email) { '' }
it { is_expected.to redirect_to new_user_session_path }
it 'redirects to the sign-in page' do
expect(subject).to redirect_to new_user_session_path
expect(controller.stored_location_for(:user)).to be_present
end
end
context 'when email is not blank' do
context 'when email is affected at an user' do
let(:email) { user.email }
it { is_expected.to redirect_to new_user_session_path }
it 'redirects to the sign-in page' do
expect(subject).to redirect_to new_user_session_path
expect(controller.stored_location_for(:user)).to be_present
end
end
context 'when email is not affected at an user' do
let(:email) { 'new_user@octo.com' }
it { is_expected.to redirect_to new_user_registration_path(user: { email: email }) }
it 'redirects to the sign-up page' do
expect(subject).to redirect_to new_user_registration_path(user: { email: email })
expect(controller.stored_location_for(:user)).to be_present
end
end
end
end
@ -213,6 +225,10 @@ describe InvitesController, type: :controller do
subject! { get :show, params: { id: invite.id } }
it 'clears the stored return location' do
expect(controller.stored_location_for(:user)).to be nil
end
context 'when invitation ID is attached at the user email account' do
let(:email) { user.email }

View file

@ -854,6 +854,11 @@ describe NewUser::DossiersController, type: :controller do
subject { get :new, params: { procedure_id: procedure_id } }
it 'clears the stored procedure context' do
subject
expect(controller.stored_location_for(:user)).to be nil
end
context 'when params procedure_id is present' do
context 'when procedure_id is valid' do
context 'when user is logged in' do

View file

@ -9,17 +9,30 @@ describe Users::RegistrationsController, type: :controller do
end
describe '#new' do
subject! { get :new }
subject { get :new }
it { expect(response).to have_http_status(:ok) }
it { expect(response).to render_template(:new) }
it { expect(subject).to have_http_status(:ok) }
it { expect(subject).to render_template(:new) }
context 'when an email address is provided' do
render_views true
subject! { get :new, params: { user: { email: 'test@exemple.fr' } } }
subject { get :new, params: { user: { email: 'test@exemple.fr' } } }
it 'prefills the form with the email address' do
expect(response.body).to include('test@exemple.fr')
expect(subject.body).to include('test@exemple.fr')
end
end
context 'when a procedure location has been stored' do
let(:procedure) { create :procedure, :published }
before do
controller.store_location_for(:user, new_dossier_path(procedure_id: procedure.id))
end
it 'makes the saved procedure available' do
expect(subject.status).to eq 200
expect(assigns(:procedure)).to eq procedure
end
end
end

View file

@ -173,38 +173,18 @@ describe Users::SessionsController, type: :controller do
describe '#new' do
subject { get :new }
context 'when procedure_id is not present in user_return_to session params' do
it { expect(subject.status).to eq 200 }
end
it { expect(subject.status).to eq 200 }
context 'when procedure_id is present in user_return_to session params' do
context 'when procedure_id does not exist' do
before do
session["user_return_to"] = '?procedure_id=0'
end
context 'when a procedure location has been stored' do
let(:procedure) { create :procedure, :published }
it { expect(subject.status).to eq 302 }
it { expect(subject).to redirect_to root_path }
before do
controller.store_location_for(:user, new_dossier_path(procedure_id: procedure.id))
end
context 'when procedure is not published' do
let(:procedure) { create :procedure }
before do
session["user_return_to"] = "?procedure_id=#{procedure.id}"
end
it { expect(subject.status).to eq 302 }
it { expect(subject).to redirect_to root_path }
end
context 'when procedure_id exist' do
let(:procedure) { create :procedure, :published }
before do
session["user_return_to"] = "?procedure_id=#{procedure.id}"
end
it { expect(subject.status).to eq 200 }
it 'makes the saved procedure available' do
expect(subject.status).to eq 200
expect(assigns(:procedure)).to eq procedure
end
end
end

View file

@ -34,7 +34,7 @@ feature 'Signing up:' do
end
context 'when visiting a procedure' do
let(:procedure) { create :simple_procedure }
let(:procedure) { create :simple_procedure, :with_service }
before do
visit commencer_path(path: procedure.path)
@ -43,13 +43,14 @@ feature 'Signing up:' do
scenario 'a new user can sign-up and fill the procedure' do
expect(page).to have_current_path new_user_session_path
click_on 'Créer un compte'
expect_page_to_have_procedure_description(procedure)
sign_up_with user_email, user_password
expect(page).to have_content "nous avons besoin de vérifier votre adresse #{user_email}"
click_confirmation_link_for user_email
expect(page).to have_content 'Votre compte a été activé'
expect(page).to have_content procedure.libelle
expect_page_to_have_procedure_description(procedure)
end
end

View file

@ -22,15 +22,12 @@ feature 'Signin in:' do
scenario 'an existing user can sign-in and fill the procedure' do
expect(page).to have_current_path new_user_session_path
expect(page).to have_content procedure.libelle
expect(page).to have_content procedure.description
expect(page).to have_content procedure.service.email
expect_page_to_have_procedure_description(procedure)
sign_in_with user.email, password
expect(page).to have_current_path identite_dossier_path(user.reload.dossiers.last)
expect(page).to have_content procedure.libelle
expect(page).to have_content procedure.description
expect_page_to_have_procedure_description(procedure)
expect(page).to have_content "Données d'identité"
end
end

View file

@ -50,6 +50,14 @@ module FeatureHelpers
visit "/users/confirmation?#{token_params}"
end
def expect_page_to_have_procedure_description(procedure)
# Procedure context on the page
expect(page).to have_content(procedure.libelle)
expect(page).to have_content(procedure.description)
# Procedure contact infos in the footer
expect(page).to have_content(procedure.service.email)
end
end
RSpec.configure do |config|