diff --git a/lib/devise/hooks/activatable.rb b/lib/devise/hooks/activatable.rb index b2eaea199f..f8b14c0ff9 100644 --- a/lib/devise/hooks/activatable.rb +++ b/lib/devise/hooks/activatable.rb @@ -7,6 +7,6 @@ if record && record.respond_to?(:active_for_authentication?) && !record.active_for_authentication? scope = options[:scope] warden.logout(scope) - throw :warden, scope: scope, message: record.inactive_message + throw :warden, scope: scope, message: record.inactive_message, locale: options[:locale] end end diff --git a/lib/devise/hooks/timeoutable.rb b/lib/devise/hooks/timeoutable.rb index 772eb142b7..655bcaa6b4 100644 --- a/lib/devise/hooks/timeoutable.rb +++ b/lib/devise/hooks/timeoutable.rb @@ -25,7 +25,7 @@ record.timedout?(last_request_at) && !proxy.remember_me_is_active?(record) Devise.sign_out_all_scopes ? proxy.sign_out : proxy.sign_out(scope) - throw :warden, scope: scope, message: :timeout + throw :warden, scope: scope, message: :timeout, locale: options[:locale] end unless env['devise.skip_trackable'] diff --git a/test/helpers/devise_helper_test.rb b/test/helpers/devise_helper_test.rb index 754e82d819..8e151c6004 100644 --- a/test/helpers/devise_helper_test.rb +++ b/test/helpers/devise_helper_test.rb @@ -14,7 +14,7 @@ class DeviseHelperTest < Devise::IntegrationTest mongoid: model_labels } - I18n.available_locales + I18n.backend.eager_load! I18n.backend.store_translations(:en, translations) end diff --git a/test/integration/activatable_test.rb b/test/integration/activatable_test.rb new file mode 100644 index 0000000000..49c3a61b52 --- /dev/null +++ b/test/integration/activatable_test.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require 'test_helper' + +class ActivatableTest < Devise::IntegrationTest + test 'shows the localized error message for inactive accounts' do + store_translations( + en: { devise: { failure: { unconfirmed: 'Unconfirmed account.' } } }, + de: { devise: { failure: { unconfirmed: 'Unbestätigtes Konto!' } } } + ) do + I18n.with_locale(:de) do + user = create_user(confirm: false, confirmation_sent_at: 1.hour.ago) + get new_user_session_path + fill_in 'email', with: user.email + fill_in 'password', with: user.password + click_button 'Log In' + + assert_contain('Unbestätigtes Konto!') + end + end + end +end diff --git a/test/integration/authenticatable_test.rb b/test/integration/authenticatable_test.rb index ea338f6fc1..045cd61715 100644 --- a/test/integration/authenticatable_test.rb +++ b/test/integration/authenticatable_test.rb @@ -334,7 +334,9 @@ class AuthenticationRedirectTest < Devise::IntegrationTest end test 'require_no_authentication should set the already_authenticated flash message as admin' do - store_translations :en, devise: { failure: { admin: { already_authenticated: 'You are already signed in as admin.' } } } do + store_translations en: { + devise: { failure: { admin: { already_authenticated: 'You are already signed in as admin.' } } } + } do sign_in_as_admin visit new_admin_session_path assert_equal "You are already signed in as admin.", flash[:alert] diff --git a/test/integration/confirmable_test.rb b/test/integration/confirmable_test.rb index c951eb0bbd..7a2b6b1aec 100644 --- a/test/integration/confirmable_test.rb +++ b/test/integration/confirmable_test.rb @@ -206,8 +206,8 @@ def resend_confirmation end test 'error message is configurable by resource name' do - store_translations :en, devise: { - failure: { user: { unconfirmed: "Not confirmed user" } } + store_translations en: { + devise: { failure: { user: { unconfirmed: "Not confirmed user" } } } } do sign_in_as_user(confirm: false) assert_contain 'Not confirmed user' diff --git a/test/integration/database_authenticatable_test.rb b/test/integration/database_authenticatable_test.rb index 20097a8718..cd950fb447 100644 --- a/test/integration/database_authenticatable_test.rb +++ b/test/integration/database_authenticatable_test.rb @@ -55,7 +55,9 @@ class DatabaseAuthenticationTest < Devise::IntegrationTest end test 'sign in with invalid email should return to sign in form with error message' do - store_translations :en, devise: { failure: { admin: { not_found_in_database: 'Invalid email address' } } } do + store_translations en: { + devise: { failure: { admin: { not_found_in_database: 'Invalid email address' } } } + } do sign_in_as_admin do fill_in 'email', with: 'wrongemail@test.com' end @@ -76,7 +78,9 @@ class DatabaseAuthenticationTest < Devise::IntegrationTest test 'when in paranoid mode and without a valid e-mail' do swap Devise, paranoid: true do - store_translations :en, devise: { failure: { not_found_in_database: 'Not found in database' } } do + store_translations en: { + devise: { failure: { not_found_in_database: 'Not found in database' } } + } do sign_in_as_user do fill_in 'email', with: 'wrongemail@test.com' end @@ -88,7 +92,9 @@ class DatabaseAuthenticationTest < Devise::IntegrationTest end test 'error message is configurable by resource name' do - store_translations :en, devise: { failure: { admin: { invalid: "Invalid credentials" } } } do + store_translations en: { + devise: { failure: { admin: { invalid: "Invalid credentials" } } } + } do sign_in_as_admin do fill_in 'password', with: 'abcdef' end diff --git a/test/integration/lockable_test.rb b/test/integration/lockable_test.rb index e5dd5ee08b..78ffc6084d 100644 --- a/test/integration/lockable_test.rb +++ b/test/integration/lockable_test.rb @@ -103,10 +103,7 @@ def send_unlock_request end test 'error message is configurable by resource name' do - store_translations :en, devise: { - failure: {user: {locked: "You are locked!"}} - } do - + store_translations en: { devise: { failure: { user: { locked: "You are locked!"} } } } do user = create_user(locked: true) user.failed_attempts = User.maximum_attempts + 1 user.save! @@ -117,10 +114,7 @@ def send_unlock_request end test "user should not be able to sign in when locked" do - store_translations :en, devise: { - failure: {user: {locked: "You are locked!"}} - } do - + store_translations en: { devise: { failure: { user: { locked: "You are locked!"} } } } do user = create_user(locked: true) user.failed_attempts = User.maximum_attempts + 1 user.save! diff --git a/test/integration/timeoutable_test.rb b/test/integration/timeoutable_test.rb index d11d59105c..f516244b67 100644 --- a/test/integration/timeoutable_test.rb +++ b/test/integration/timeoutable_test.rb @@ -141,9 +141,7 @@ def last_request_at end test 'error message with i18n' do - store_translations :en, devise: { - failure: { user: { timeout: 'Session expired!' } } - } do + store_translations en: { devise: { failure: { user: { timeout: 'Session expired!' } } } } do user = sign_in_as_user get expire_user_path(user) @@ -154,9 +152,7 @@ def last_request_at end test 'error message with i18n with double redirect' do - store_translations :en, devise: { - failure: { user: { timeout: 'Session expired!' } } - } do + store_translations en: { devise: { failure: { user: { timeout: 'Session expired!' } } } } do user = sign_in_as_user get expire_user_path(user) @@ -167,6 +163,24 @@ def last_request_at end end + test 'shows the localized error message on session timeout' do + # Set up the error message in the default and in a different locale + store_translations( + en: { devise: { failure: { user: { timeout: 'Session expired!' } } } }, + de: { devise: { failure: { timeout: 'Sitzung abgelaufen!' } } } + ) do + I18n.with_locale(:de) do + user = sign_in_as_user + + get expire_user_path(user) + get users_path + follow_redirect! + follow_redirect! + assert_contain('Sitzung abgelaufen!') + end + end + end + test 'time out not triggered if remembered' do user = sign_in_as_user remember_me: true get expire_user_path(user) diff --git a/test/mailers/confirmation_instructions_test.rb b/test/mailers/confirmation_instructions_test.rb index 5b46331219..e339736a54 100644 --- a/test/mailers/confirmation_instructions_test.rb +++ b/test/mailers/confirmation_instructions_test.rb @@ -69,13 +69,17 @@ def mail end test 'set up subject from I18n' do - store_translations :en, devise: { mailer: { confirmation_instructions: { subject: 'Account Confirmation' } } } do + store_translations en: { + devise: { mailer: { confirmation_instructions: { subject: 'Account Confirmation' } } } + } do assert_equal 'Account Confirmation', mail.subject end end test 'subject namespaced by model' do - store_translations :en, devise: { mailer: { confirmation_instructions: { user_subject: 'User Account Confirmation' } } } do + store_translations en: { + devise: { mailer: { confirmation_instructions: { user_subject: 'User Account Confirmation' } } } + } do assert_equal 'User Account Confirmation', mail.subject end end diff --git a/test/mailers/email_changed_test.rb b/test/mailers/email_changed_test.rb index f324165452..8cf26b3759 100644 --- a/test/mailers/email_changed_test.rb +++ b/test/mailers/email_changed_test.rb @@ -73,13 +73,17 @@ def mail end test 'set up subject from I18n' do - store_translations :en, devise: { mailer: { email_changed: { subject: 'Email Has Changed' } } } do + store_translations en: { + devise: { mailer: { email_changed: { subject: 'Email Has Changed' } } } + } do assert_equal 'Email Has Changed', mail.subject end end test 'subject namespaced by model' do - store_translations :en, devise: { mailer: { email_changed: { user_subject: 'User Email Has Changed' } } } do + store_translations en: { + devise: { mailer: { email_changed: { user_subject: 'User Email Has Changed' } } } + } do assert_equal 'User Email Has Changed', mail.subject end end diff --git a/test/mailers/reset_password_instructions_test.rb b/test/mailers/reset_password_instructions_test.rb index 5a344cbf09..164fb7d79e 100644 --- a/test/mailers/reset_password_instructions_test.rb +++ b/test/mailers/reset_password_instructions_test.rb @@ -65,13 +65,17 @@ def mail end test 'set up subject from I18n' do - store_translations :en, devise: { mailer: { reset_password_instructions: { subject: 'Reset instructions' } } } do + store_translations en: { + devise: { mailer: { reset_password_instructions: { subject: 'Reset instructions' } } } + } do assert_equal 'Reset instructions', mail.subject end end test 'subject namespaced by model' do - store_translations :en, devise: { mailer: { reset_password_instructions: { user_subject: 'User Reset Instructions' } } } do + store_translations en: { + devise: { mailer: { reset_password_instructions: { user_subject: 'User Reset Instructions' } } } + } do assert_equal 'User Reset Instructions', mail.subject end end diff --git a/test/mailers/unlock_instructions_test.rb b/test/mailers/unlock_instructions_test.rb index dff580e2eb..e7cc0031d8 100644 --- a/test/mailers/unlock_instructions_test.rb +++ b/test/mailers/unlock_instructions_test.rb @@ -66,13 +66,17 @@ def mail end test 'set up subject from I18n' do - store_translations :en, devise: { mailer: { unlock_instructions: { subject: 'Yo unlock instructions' } } } do + store_translations en: { + devise: { mailer: { unlock_instructions: { subject: 'Yo unlock instructions' } } } + } do assert_equal 'Yo unlock instructions', mail.subject end end test 'subject namespaced by model' do - store_translations :en, devise: { mailer: { unlock_instructions: { user_subject: 'User Unlock Instructions' } } } do + store_translations en: { + devise: { mailer: { unlock_instructions: { user_subject: 'User Unlock Instructions' } } } + } do assert_equal 'User Unlock Instructions', mail.subject end end diff --git a/test/support/helpers.rb b/test/support/helpers.rb index 01dc6aa562..3b237c5d07 100644 --- a/test/support/helpers.rb +++ b/test/support/helpers.rb @@ -7,13 +7,12 @@ def setup_mailer ActionMailer::Base.deliveries = [] end - def store_translations(locale, translations, &block) - # Calling 'available_locales' before storing the translations to ensure - # that the I18n backend will be initialized before we store our custom - # translations, so they will always override the translations for the - # YML file. - I18n.available_locales - I18n.backend.store_translations(locale, translations) + def store_translations(translations) + # Eager-loading the backend before storing the translations ensures that the I18n backend will + # always be initialized before we store our custom translations, so the test-specific + # translations override the translations from the YML files. + I18n.backend.eager_load! + translations.each { |locale, entries| I18n.backend.store_translations(locale, entries) } yield ensure I18n.reload! diff --git a/test/test_helper.rb b/test/test_helper.rb index e6df812037..8cde508472 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -11,6 +11,8 @@ require "orm/#{DEVISE_ORM}" I18n.load_path.concat Dir["#{File.dirname(__FILE__)}/support/locale/*.yml"] +# Allow setting test-specific locales even if they are not defined in the locale YAML files. +I18n.enforce_available_locales = false require 'mocha/minitest' require 'timecop'