Merge pull request #6360 from betagouv/redirect-to-sign-in-on-autosave-401
En cas de déconnexion, l'Usager en train de remplir un formulaire est redirigé vers la page de connexion (#6360)
This commit is contained in:
commit
0202747a9d
5 changed files with 59 additions and 5 deletions
|
@ -10,7 +10,7 @@ export default class AutoSaveController {
|
||||||
|
|
||||||
// Add a new autosave request to the queue.
|
// Add a new autosave request to the queue.
|
||||||
// It will be started after the previous one finishes (to prevent older form data
|
// It will be started after the previous one finishes (to prevent older form data
|
||||||
// to overwrite newer data if the server does not repond in order.)
|
// to overwrite newer data if the server does not respond in order.)
|
||||||
enqueueAutosaveRequest(form) {
|
enqueueAutosaveRequest(form) {
|
||||||
this.latestPromise = this.latestPromise.finally(() => {
|
this.latestPromise = this.latestPromise.finally(() => {
|
||||||
return this._sendAutosaveRequest(form)
|
return this._sendAutosaveRequest(form)
|
||||||
|
|
|
@ -62,6 +62,15 @@ addEventListener('autosave:end', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
addEventListener('autosave:error', (event) => {
|
addEventListener('autosave:error', (event) => {
|
||||||
|
let error = event.detail;
|
||||||
|
|
||||||
|
if (error.xhr.status == 401) {
|
||||||
|
// If we are unauthenticated, reload the page using a GET request.
|
||||||
|
// This will allow Devise to properly redirect us to sign-in, and then back to this page.
|
||||||
|
document.location.reload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
enable(document.querySelector('button.autosave-retry'));
|
enable(document.querySelector('button.autosave-retry'));
|
||||||
setState('failed');
|
setState('failed');
|
||||||
logError(event.detail);
|
logError(event.detail);
|
||||||
|
|
|
@ -50,6 +50,13 @@ export function delegate(eventNames, selector, callback) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A promise-based wrapper for Rails.ajax().
|
||||||
|
//
|
||||||
|
// Returns a Promise that is either:
|
||||||
|
// - resolved in case of a 20* HTTP response code,
|
||||||
|
// - rejected with an Error object otherwise.
|
||||||
|
//
|
||||||
|
// See Rails.ajax() code for more details.
|
||||||
export function ajax(options) {
|
export function ajax(options) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
Object.assign(options, {
|
Object.assign(options, {
|
||||||
|
@ -57,7 +64,10 @@ export function ajax(options) {
|
||||||
resolve({ response, statusText, xhr });
|
resolve({ response, statusText, xhr });
|
||||||
},
|
},
|
||||||
error: (response, statusText, xhr) => {
|
error: (response, statusText, xhr) => {
|
||||||
let error = new Error(`Erreur ${xhr.status} : ${statusText}`);
|
// NB: on HTTP/2 connections, statusText is always empty.
|
||||||
|
let error = new Error(
|
||||||
|
`Erreur ${xhr.status}` + (statusText ? ` : ${statusText}` : '')
|
||||||
|
);
|
||||||
Object.assign(error, { response, statusText, xhr });
|
Object.assign(error, { response, statusText, xhr });
|
||||||
reject(error);
|
reject(error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,24 +255,46 @@ feature 'The user' do
|
||||||
expect(page).to have_field('texte obligatoire', with: 'a valid user input')
|
expect(page).to have_field('texte obligatoire', with: 'a valid user input')
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'retry on autosave error', js: true do
|
scenario 'retry on autosave error', :capybara_ignore_server_errors, js: true do
|
||||||
log_in(user, simple_procedure)
|
log_in(user, simple_procedure)
|
||||||
fill_individual
|
fill_individual
|
||||||
|
|
||||||
# Test autosave failure
|
# Test autosave failure
|
||||||
logout(:user) # Make the subsequent autosave requests fail
|
allow_any_instance_of(Users::DossiersController).to receive(:update_brouillon).and_raise("Server is busy")
|
||||||
fill_in('texte obligatoire', with: 'a valid user input')
|
fill_in('texte obligatoire', with: 'a valid user input')
|
||||||
blur
|
blur
|
||||||
expect(page).to have_css('span', text: 'Impossible d’enregistrer le brouillon', visible: true)
|
expect(page).to have_css('span', text: 'Impossible d’enregistrer le brouillon', visible: true)
|
||||||
|
|
||||||
# Test that retrying after a failure works
|
# Test that retrying after a failure works
|
||||||
login_as(user, scope: :user) # Make the autosave requests work again
|
allow_any_instance_of(Users::DossiersController).to receive(:update_brouillon).and_call_original
|
||||||
click_on 'réessayer'
|
click_on 'réessayer'
|
||||||
expect(page).to have_css('span', text: 'Brouillon enregistré', visible: true)
|
expect(page).to have_css('span', text: 'Brouillon enregistré', visible: true)
|
||||||
|
|
||||||
visit current_path
|
visit current_path
|
||||||
expect(page).to have_field('texte obligatoire', with: 'a valid user input')
|
expect(page).to have_field('texte obligatoire', with: 'a valid user input')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scenario 'autosave redirects to sign-in after being disconnected', js: true 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')
|
||||||
|
blur
|
||||||
|
|
||||||
|
# … 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')
|
||||||
|
blur
|
||||||
|
expect(page).to have_css('span', text: 'Brouillon enregistré', visible: true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -47,3 +47,16 @@ Capybara::Screenshot.prune_strategy = :keep_last_run
|
||||||
Capybara::Screenshot.register_driver :headless_chrome do |driver, path|
|
Capybara::Screenshot.register_driver :headless_chrome do |driver, path|
|
||||||
driver.browser.save_screenshot(path)
|
driver.browser.save_screenshot(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
RSpec.configure do |config|
|
||||||
|
# Examples tagged with :capybara_ignore_server_errors will allow Capybara
|
||||||
|
# to continue when an exception in raised by Rails.
|
||||||
|
# This allows to test for error cases.
|
||||||
|
config.around(:each, :capybara_ignore_server_errors) do |example|
|
||||||
|
Capybara.raise_server_errors = false
|
||||||
|
|
||||||
|
example.run
|
||||||
|
ensure
|
||||||
|
Capybara.raise_server_errors = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in a new issue