Skip to content

Commit

Permalink
Create custom subclass of I18n::Config to separate GoodJob-specific…
Browse files Browse the repository at this point in the history
… locales and default locale (#1001)
  • Loading branch information
bensheldon authored Jul 10, 2023
1 parent e6be97f commit dc4f33f
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 12 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ Rails.application.configure do
config.good_job.shutdown_timeout = 25 # seconds
config.good_job.enable_cron = true
config.good_job.cron = { example: { cron: '0 * * * *', class: 'ExampleJob' } }
config.good_job.dashboard_default_locale = :en
# ...or all at once.
config.good_job = {
Expand All @@ -262,6 +263,7 @@ Rails.application.configure do
class: 'ExampleJob'
},
},
dashboard_default_locale: :en,
}
end
```
Expand Down
24 changes: 15 additions & 9 deletions app/controllers/good_job/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module GoodJob
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception

around_action :switch_locale
around_action :use_good_job_locale

content_security_policy do |policy|
policy.default_src(:none) if policy.default_src(*policy.default_src).blank?
Expand All @@ -31,25 +31,31 @@ def default_url_options(options = {})
{ locale: I18n.locale }.merge(options)
end

def switch_locale(&action)
def use_good_job_locale(&action)
@original_i18n_config = I18n.config
I18n.config = ::GoodJob::I18nConfig.new
I18n.with_locale(current_locale, &action)
ensure
I18n.config = @original_i18n_config
@original_i18n_config = nil
end

def use_original_locale
prev_config = I18n.config
I18n.config = @original_i18n_config if @original_i18n_config
yield
ensure
I18n.config = prev_config
end

def current_locale
if request.GET['locale']
request.GET['locale']
elsif params[:locale]
params[:locale]
elsif good_job_available_locales.exclude?(I18n.default_locale) && I18n.available_locales.include?(:en)
:en
else
I18n.default_locale
end
end

def good_job_available_locales
@_good_job_available_locales ||= GoodJob::Engine.root.join("config/locales").glob("*.yml").map { |path| File.basename(path, ".yml").to_sym }.uniq
end
helper_method :good_job_available_locales
end
end
2 changes: 1 addition & 1 deletion app/controllers/good_job/cron_entries_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def show

def enqueue
@cron_entry = CronEntry.find(params[:cron_key])
@cron_entry.enqueue(Time.current)
use_original_locale { @cron_entry.enqueue(Time.current) }
redirect_back(fallback_location: cron_entries_path, notice: t(".notice"))
end

Expand Down
1 change: 0 additions & 1 deletion app/helpers/good_job/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ def translate_hash(key, **options)
end

def translation_exists?(key, **options)
true if good_job_available_locales.include?(I18n.locale)
I18n.exists?(scope_key_by_partial(key), **options)
end
end
Expand Down
25 changes: 25 additions & 0 deletions app/models/good_job/i18n_config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

module GoodJob
class I18nConfig < ::I18n::Config
BACKEND = I18n::Backend::Simple.new
AVAILABLE_LOCALES = GoodJob::Engine.root.join("config/locales").glob("*.yml").map { |path| File.basename(path, ".yml").to_sym }.uniq
AVAILABLE_LOCALES_SET = AVAILABLE_LOCALES.inject(Set.new) { |set, locale| set << locale.to_s << locale.to_sym }

def backend
BACKEND
end

def available_locales
AVAILABLE_LOCALES
end

def available_locales_set
AVAILABLE_LOCALES_SET
end

def default_locale
GoodJob.configuration.dashboard_default_locale
end
end
end
2 changes: 1 addition & 1 deletion app/views/good_job/shared/_navbar.erb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
</a>

<ul class="dropdown-menu" aria-labelledby="localeOptions">
<% possible_locales = I18n.enforce_available_locales ? (good_job_available_locales & I18n.available_locales) : good_job_available_locales %>
<% possible_locales = I18n.available_locales %>
<% possible_locales.reject { |locale| locale == I18n.locale }.each do |locale| %>
<li><%= link_to locale, url_for(locale: locale), class: "dropdown-item" %></li>
<% end %>
Expand Down
6 changes: 6 additions & 0 deletions lib/good_job/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class Configuration
DEFAULT_ENABLE_CRON = false
# Default to enabling LISTEN/NOTIFY
DEFAULT_ENABLE_LISTEN_NOTIFY = true
# Default Dashboard I18n locale
DEFAULT_DASHBOARD_DEFAULT_LOCALE = :en

def self.validate_execution_mode(execution_mode)
raise ArgumentError, "GoodJob execution mode must be one of #{EXECUTION_MODES.join(', ')}. It was '#{execution_mode}' which is not valid." unless execution_mode.in?(EXECUTION_MODES)
Expand Down Expand Up @@ -346,6 +348,10 @@ def smaller_number_is_higher_priority
rails_config[:smaller_number_is_higher_priority]
end

def dashboard_default_locale
rails_config[:dashboard_default_locale] || DEFAULT_DASHBOARD_DEFAULT_LOCALE
end

private

def rails_config
Expand Down
8 changes: 8 additions & 0 deletions spec/lib/good_job/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -280,4 +280,12 @@
expect(configuration.smaller_number_is_higher_priority).to be true
end
end

describe '#dashboard_default_locale' do
it 'delegates to rails configuration' do
allow(Rails.application.config).to receive(:good_job).and_return({ dashboard_default_locale: :de })
configuration = described_class.new({})
expect(configuration.dashboard_default_locale).to eq :de
end
end
end
23 changes: 23 additions & 0 deletions spec/requests/good_job/cron_entries_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,27 @@
expect(response).to have_http_status(:found)
end
end

describe 'POST #enqueue' do
before do
allow(ExampleJob).to receive(:queue_adapter).and_return(GoodJob::Adapter.new(execution_mode: :external))
end

it 'enqueues a job' do
expect do
post good_job.enqueue_cron_entry_path(cron_key: 'example')
end.to change(GoodJob::Job, :count).by(1)
expect(response).to have_http_status(:found)
end

it 'uses the application I18n.default_locale' do
original_locale = I18n.default_locale
I18n.default_locale = :de

post good_job.enqueue_cron_entry_path(cron_key: 'example')
expect(GoodJob::Job.last.serialized_params).to include("locale" => "de")
ensure
I18n.default_locale = original_locale
end
end
end
4 changes: 4 additions & 0 deletions spec/test_app/config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,9 @@ class Application < Rails::Application
config.log_level = :debug

config.action_controller.include_all_helpers = false

# Set default locale to something not yet translated for GoodJob
# config.i18n.available_locales = [:pt]
# config.i18n.default_locale = :pt
end
end

0 comments on commit dc4f33f

Please sign in to comment.