Bugfix: Always use the default language when generating emails.

There was a race condition issue when the application was generating an
email and was using a language that was previously being used in other
request.
This commit is contained in:
Ruben Davila 2017-05-25 10:22:45 -05:00
parent d07e85e103
commit 5c921809cd
7 changed files with 62 additions and 29 deletions

View File

@ -275,11 +275,7 @@ class ApplicationController < ActionController::Base
request.base_url
end
def set_locale
Gitlab::I18n.set_locale(current_user)
yield
ensure
Gitlab::I18n.reset_locale
def set_locale(&block)
Gitlab::I18n.with_user_locale(current_user, &block)
end
end

View File

@ -1,4 +1,6 @@
class BaseMailer < ActionMailer::Base
around_action :render_with_default_locale
helper ApplicationHelper
helper MarkupHelper
@ -14,6 +16,10 @@ class BaseMailer < ActionMailer::Base
private
def render_with_default_locale(&block)
Gitlab::I18n.with_default_locale(&block)
end
def default_sender_address
address = Mail::Address.new(Gitlab.config.gitlab.email_from)
address.display_name = Gitlab.config.gitlab.email_display_name

View File

@ -1,5 +1,6 @@
FastGettext.add_text_domain 'gitlab', path: File.join(Rails.root, 'locale'), type: :po
FastGettext.default_text_domain = 'gitlab'
FastGettext.default_available_locales = Gitlab::I18n.available_locales
FastGettext.default_locale = :en
I18n.available_locales = Gitlab::I18n.available_locales

View File

@ -45,9 +45,9 @@ module API
end
before { allow_access_with_scope :api }
before { Gitlab::I18n.set_locale(current_user) }
before { Gitlab::I18n.locale = current_user&.preferred_language }
after { Gitlab::I18n.reset_locale }
after { Gitlab::I18n.use_default_locale }
rescue_from Gitlab::Access::AccessDeniedError do
rack_response({ 'message' => '403 Forbidden' }.to_json, 403)

View File

@ -12,15 +12,36 @@ module Gitlab
AVAILABLE_LANGUAGES.keys
end
def set_locale(current_user)
requested_locale = current_user&.preferred_language || ::I18n.default_locale
locale = FastGettext.set_locale(requested_locale)
::I18n.locale = locale
def locale
FastGettext.locale
end
def reset_locale
def locale=(locale_string)
requested_locale = locale_string || ::I18n.default_locale
new_locale = FastGettext.set_locale(requested_locale)
::I18n.locale = new_locale
end
def use_default_locale
FastGettext.set_locale(::I18n.default_locale)
::I18n.locale = ::I18n.default_locale
end
def with_locale(locale_string)
original_locale = locale
self.locale = locale_string
yield
ensure
self.locale = original_locale
end
def with_user_locale(user, &block)
with_locale(user&.preferred_language, &block)
end
def with_default_locale(&block)
with_locale(::I18n.default_locale, &block)
end
end
end

View File

@ -1,27 +1,27 @@
require 'spec_helper'
module Gitlab
describe I18n, lib: true do
let(:user) { create(:user, preferred_language: 'es') }
describe Gitlab::I18n, lib: true do
let(:user) { create(:user, preferred_language: 'es') }
describe '.set_locale' do
it 'sets the locale based on current user preferred language' do
Gitlab::I18n.set_locale(user)
describe '.locale=' do
after { described_class.use_default_locale }
expect(FastGettext.locale).to eq('es')
expect(::I18n.locale).to eq(:es)
end
it 'sets the locale based on current user preferred language' do
described_class.locale = user.preferred_language
expect(FastGettext.locale).to eq('es')
expect(::I18n.locale).to eq(:es)
end
end
describe '.reset_locale' do
it 'resets the locale to the default language' do
Gitlab::I18n.set_locale(user)
describe '.use_default_locale' do
it 'resets the locale to the default language' do
described_class.locale = user.preferred_language
Gitlab::I18n.reset_locale
described_class.use_default_locale
expect(FastGettext.locale).to eq('en')
expect(::I18n.locale).to eq(:en)
end
expect(FastGettext.locale).to eq('en')
expect(::I18n.locale).to eq(:en)
end
end
end

View File

@ -128,6 +128,15 @@ describe Notify do
is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue))
end
end
context 'with a preferred language' do
before { Gitlab::I18n.locale = :es }
after { Gitlab::I18n.use_default_locale }
it 'always generates the email using the default language' do
is_expected.to have_body_text('foo, bar, and baz')
end
end
end
describe 'status changed' do