about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2019-07-21 18:08:02 +0200
committerGitHub <noreply@github.com>2019-07-21 18:08:02 +0200
commitbd1545de5ee9655130e5357bb9cb6449520a6292 (patch)
treeaf0b640a9b337e291622585e2986e516170f88b7
parentbd87e6667975bc3b5bfaf3e1cdff97e041ed4c98 (diff)
Change locale detection to run once per session (#8657)
Fix #6462
-rw-r--r--app/controllers/application_controller.rb6
-rw-r--r--app/controllers/concerns/localized.rb13
-rw-r--r--config/application.rb3
-rw-r--r--spec/controllers/concerns/localized_spec.rb16
4 files changed, 17 insertions, 21 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 51e9764d4..5863fe168 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -138,11 +138,7 @@ class ApplicationController < ActionController::Base
   def respond_with_error(code)
     respond_to do |format|
       format.any  { head code }
-
-      format.html do
-        set_locale
-        render "errors/#{code}", layout: 'error', status: code
-      end
+      format.html { render "errors/#{code}", layout: 'error', status: code }
     end
   end
 
diff --git a/app/controllers/concerns/localized.rb b/app/controllers/concerns/localized.rb
index 145549bcd..b43859d9d 100644
--- a/app/controllers/concerns/localized.rb
+++ b/app/controllers/concerns/localized.rb
@@ -4,16 +4,19 @@ module Localized
   extend ActiveSupport::Concern
 
   included do
-    before_action :set_locale
+    around_action :set_locale
   end
 
   private
 
   def set_locale
-    I18n.locale = default_locale
-    I18n.locale = current_user.locale if user_signed_in?
-  rescue I18n::InvalidLocale
-    I18n.locale = default_locale
+    locale   = current_user.locale if respond_to?(:user_signed_in?) && user_signed_in?
+    locale ||= session[:locale] ||= default_locale
+    locale   = default_locale unless I18n.available_locales.include?(locale.to_sym)
+
+    I18n.with_locale(locale) do
+      yield
+    end
   end
 
   def default_locale
diff --git a/config/application.rb b/config/application.rb
index 4534ede49..f49deffbb 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -114,6 +114,9 @@ module Mastodon
       Doorkeeper::AuthorizationsController.layout 'modal'
       Doorkeeper::AuthorizedApplicationsController.layout 'admin'
       Doorkeeper::Application.send :include, ApplicationExtension
+      Devise::FailureApp.send :include, AbstractController::Callbacks
+      Devise::FailureApp.send :include, HttpAcceptLanguage::EasyAccess
+      Devise::FailureApp.send :include, Localized
     end
   end
 end
diff --git a/spec/controllers/concerns/localized_spec.rb b/spec/controllers/concerns/localized_spec.rb
index 76c3de118..7635d10e1 100644
--- a/spec/controllers/concerns/localized_spec.rb
+++ b/spec/controllers/concerns/localized_spec.rb
@@ -7,16 +7,10 @@ describe ApplicationController, type: :controller do
     include Localized
 
     def success
-      head 200
+      render plain: I18n.locale, status: 200
     end
   end
 
-  around do |example|
-    current_locale = I18n.locale
-    example.run
-    I18n.locale = current_locale
-  end
-
   before do
     routes.draw { get 'success' => 'anonymous#success' }
   end
@@ -25,19 +19,19 @@ describe ApplicationController, type: :controller do
     it 'sets available and preferred language' do
       request.headers['Accept-Language'] = 'ca-ES, fa'
       get 'success'
-      expect(I18n.locale).to eq :fa
+      expect(response.body).to eq 'fa'
     end
 
     it 'sets available and compatible language if none of available languages are preferred' do
       request.headers['Accept-Language'] = 'fa-IR'
       get 'success'
-      expect(I18n.locale).to eq :fa
+      expect(response.body).to eq 'fa'
     end
 
     it 'sets default locale if none of available languages are compatible' do
       request.headers['Accept-Language'] = ''
       get 'success'
-      expect(I18n.locale).to eq :en
+      expect(response.body).to eq 'en'
     end
   end
 
@@ -48,7 +42,7 @@ describe ApplicationController, type: :controller do
       sign_in(user)
       get 'success'
 
-      expect(I18n.locale).to eq :ca
+      expect(response.body).to eq 'ca'
     end
   end