From b788948985e532e5d8b39c3d07927abf736094eb Mon Sep 17 00:00:00 2001 From: Gerhard Schlager Date: Wed, 15 May 2019 23:43:00 +0200 Subject: [PATCH] FEATURE: English locale with international date formats Makes en_US the new default locale --- Dangerfile | 4 +- app/assets/javascripts/locales/en_US.js.erb | 5 ++ .../javascripts/wizard/test/test_helper.js | 2 +- app/controllers/application_controller.rb | 2 +- app/jobs/base.rb | 2 +- app/models/locale_site_setting.rb | 7 +++ app/models/translation_override.rb | 3 +- config/locales/client.en.yml | 31 ++++++----- config/locales/client.en_US.yml | 38 +++++++++++++ config/locales/names.yml | 3 + config/locales/server.en.yml | 23 ++++---- config/locales/server.en_US.yml | 25 +++++++++ config/site_settings.yml | 5 ++ .../20190430135846_migrate_english_locale.rb | 55 +++++++++++++++++++ lib/js_locale_helper.rb | 29 +++++++--- lib/site_settings/defaults_provider.rb | 2 +- lib/text_cleaner.rb | 2 +- .../quote_generator.rb | 2 +- script/bulk_import/base.rb | 2 +- script/pull_translations.rb | 2 +- .../translate_accelerator_spec.rb | 2 + spec/components/js_locale_helper_spec.rb | 13 ++++- .../components/site_setting_extension_spec.rb | 4 +- spec/components/text_cleaner_spec.rb | 4 ++ .../theme_store/tgz_exporter_spec.rb | 2 +- spec/components/wizard/step_updater_spec.rb | 3 +- spec/integrity/i18n_spec.rb | 7 ++- .../i18n}/discourse_i18n_spec.rb | 0 .../i18n}/fallback_locale_list_spec.rb | 8 +++ .../i18n_interpolation_keys_finder_spec.rb | 0 spec/mailers/user_notifications_spec.rb | 6 +- spec/models/badge_spec.rb | 6 +- spec/models/locale_site_setting_spec.rb | 20 +++++-- spec/models/theme_field_spec.rb | 16 +++--- spec/models/theme_spec.rb | 6 +- spec/models/translation_override_spec.rb | 2 +- spec/multisite/site_settings_spec.rb | 4 +- spec/rails_helper.rb | 2 +- .../admin/site_texts_controller_spec.rb | 2 +- .../requests/extra_locales_controller_spec.rb | 5 +- spec/services/search_indexer_spec.rb | 2 +- .../components/d-editor-test.js.es6 | 2 +- test/javascripts/fixtures/about.js.es6 | 2 +- test/javascripts/test_helper.js | 2 +- 44 files changed, 274 insertions(+), 90 deletions(-) create mode 100644 app/assets/javascripts/locales/en_US.js.erb create mode 100644 config/locales/client.en_US.yml create mode 100644 config/locales/server.en_US.yml create mode 100644 db/migrate/20190430135846_migrate_english_locale.rb rename spec/{components => lib/i18n}/discourse_i18n_spec.rb (100%) rename spec/{components => lib/i18n}/fallback_locale_list_spec.rb (84%) rename spec/{services => lib/i18n}/i18n_interpolation_keys_finder_spec.rb (100%) diff --git a/Dangerfile b/Dangerfile index 72c02d7c78b..667918b36a7 100644 --- a/Dangerfile +++ b/Dangerfile @@ -13,8 +13,8 @@ This PR doesn't match our required code formatting standards, as enforced by pre }) end -locales_changes = git.modified_files.grep(/config\/locales/) -has_non_en_locales_changes = locales_changes.grep_v(/config\/locales\/(client|server)\.en\.yml/).any? +locales_changes = git.modified_files.grep(%r{config/locales}) +has_non_en_locales_changes = locales_changes.grep_v(%r{config/locales/(?:client|server)\.(?:en|en_US)\.yml}).any? if locales_changes.any? && has_non_en_locales_changes fail("Please submit your non-English translation updates via [Transifex](https://www.transifex.com/discourse/discourse-org/). You can read more on how to contribute translations [here](https://meta.discourse.org/t/contribute-a-translation-to-discourse/14882).") diff --git a/app/assets/javascripts/locales/en_US.js.erb b/app/assets/javascripts/locales/en_US.js.erb new file mode 100644 index 00000000000..7c4cccccf85 --- /dev/null +++ b/app/assets/javascripts/locales/en_US.js.erb @@ -0,0 +1,5 @@ +//= depend_on 'client.en_US.yml' +//= require locales/i18n + +<% JsLocaleHelper.reloadable_plugins(:en_US, self) %> +<%= JsLocaleHelper.output_locale(:en_US) %> diff --git a/app/assets/javascripts/wizard/test/test_helper.js b/app/assets/javascripts/wizard/test/test_helper.js index fada8026aed..3d26843532f 100644 --- a/app/assets/javascripts/wizard/test/test_helper.js +++ b/app/assets/javascripts/wizard/test/test_helper.js @@ -17,7 +17,7 @@ //= require_tree ./acceptance //= require_tree ./models //= require_tree ./components -//= require locales/en +//= require locales/en_US //= require fake_xml_http_request //= require route-recognizer/dist/route-recognizer //= require pretender/pretender diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 892380ab198..107523388e3 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -324,7 +324,7 @@ class ApplicationController < ActionController::Base locale = current_user.effective_locale end - I18n.locale = I18n.locale_available?(locale) ? locale : :en + I18n.locale = I18n.locale_available?(locale) ? locale : SiteSettings::DefaultsProvider::DEFAULT_LOCALE I18n.ensure_all_loaded! end diff --git a/app/jobs/base.rb b/app/jobs/base.rb index b34e3f1c2b0..aae9c8a1071 100644 --- a/app/jobs/base.rb +++ b/app/jobs/base.rb @@ -221,7 +221,7 @@ module Jobs RailsMultisite::ConnectionManagement.with_connection(db) do job_instrumenter = JobInstrumenter.new(job_class: self.class, opts: opts, db: db, jid: jid) begin - I18n.locale = SiteSetting.default_locale || "en" + I18n.locale = SiteSetting.default_locale || SiteSettings::DefaultsProvider::DEFAULT_LOCALE I18n.ensure_all_loaded! begin logster_env = {} diff --git a/app/models/locale_site_setting.rb b/app/models/locale_site_setting.rb index 5f3d7f1abe2..4e5522a4789 100644 --- a/app/models/locale_site_setting.rb +++ b/app/models/locale_site_setting.rb @@ -57,7 +57,14 @@ class LocaleSiteSetting < EnumSiteSetting end end + FALLBACKS ||= { + en_US: :en + } + def self.fallback_locale(locale) + fallback_locale = FALLBACKS[locale.to_sym] + return fallback_locale if fallback_locale + plugin_locale = DiscoursePluginRegistry.locales[locale.to_s] plugin_locale ? plugin_locale[:fallbackLocale]&.to_sym : nil end diff --git a/app/models/translation_override.rb b/app/models/translation_override.rb index 3d205f1d62d..9dcf7189192 100644 --- a/app/models/translation_override.rb +++ b/app/models/translation_override.rb @@ -66,8 +66,7 @@ class TranslationOverride < ActiveRecord::Base def check_interpolation_keys original_text = I18n.overrides_disabled do - # lookup is protected - I18n.backend.send(:lookup, self.locale, self.translation_key) + I18n.t(translation_key, locale: :en) end if original_text diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 01f47130742..c51848c5bee 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -38,31 +38,31 @@ en: millions: "{{number}}M" dates: # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ - time: "h:mm a" + time: "HH:mm" # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ timeline_date: "MMM YYYY" # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ - long_no_year: "MMM D h:mm a" + long_no_year: "D MMM HH:mm" # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ - long_no_year_no_time: "MMM D" + long_no_year_no_time: "D MMM" # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ - full_no_year_no_time: "MMMM Do" + full_no_year_no_time: "Do MMMM" # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ - long_with_year: "MMM D, YYYY h:mm a" + long_with_year: "D MMM YYYY HH:mm" # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ - long_with_year_no_time: "MMM D, YYYY" + long_with_year_no_time: "D MMM YYYY" # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ - full_with_year_no_time: "MMMM Do, YYYY" + full_with_year_no_time: "D MMMM YYYY" # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ - long_date_with_year: "MMM D, 'YY LT" + long_date_with_year: "D MMM 'YY LT" # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ - long_date_without_year: "MMM D, LT" + long_date_without_year: "D MMM LT" # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ - long_date_with_year_without_time: "MMM D, 'YY" + long_date_with_year_without_time: "D MMM 'YY" # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ - long_date_without_year_with_linebreak: "MMM D
LT" + long_date_without_year_with_linebreak: "D MMM
LT" # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ - long_date_with_year_with_linebreak: "MMM D, 'YY
LT" + long_date_with_year_with_linebreak: "D MMM 'YY
LT" wrap_ago: "%{date} ago" @@ -98,7 +98,9 @@ en: almost_x_years: one: "1y" other: "%{count}y" - date_month: "MMM D" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + date_month: "D MMM" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ date_year: "MMM 'YY" medium: x_minutes: @@ -110,7 +112,8 @@ en: x_days: one: "1 day" other: "%{count} days" - date_year: "MMM D, 'YY" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + date_year: "D MMM 'YY" medium_with_ago: x_minutes: one: "1 min ago" diff --git a/config/locales/client.en_US.yml b/config/locales/client.en_US.yml new file mode 100644 index 00000000000..683baf554dd --- /dev/null +++ b/config/locales/client.en_US.yml @@ -0,0 +1,38 @@ +en_US: + js: + dates: + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + time: "h:mm a" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + timeline_date: "MMM YYYY" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + long_no_year: "MMM D h:mm a" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + long_no_year_no_time: "MMM D" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + full_no_year_no_time: "MMMM Do" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + long_with_year: "MMM D, YYYY h:mm a" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + long_with_year_no_time: "MMM D, YYYY" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + full_with_year_no_time: "MMMM Do, YYYY" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + long_date_with_year: "MMM D, 'YY LT" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + long_date_without_year: "MMM D, LT" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + long_date_with_year_without_time: "MMM D, 'YY" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + long_date_without_year_with_linebreak: "MMM D
LT" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + long_date_with_year_with_linebreak: "MMM D, 'YY
LT" + + tiny: + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + date_month: "MMM D" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + date_year: "MMM 'YY" + medium: + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + date_year: "MMM D, 'YY" diff --git a/config/locales/names.yml b/config/locales/names.yml index 764cdff0a06..c6b2c6dadea 100644 --- a/config/locales/names.yml +++ b/config/locales/names.yml @@ -113,6 +113,9 @@ el: en: name: English nativeName: English +en_US: + name: English (United States) + nativeName: English (United States) eo: name: Esperanto nativeName: Esperanto diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index c32831dd743..200e0dde5ba 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -19,21 +19,21 @@ en: # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ short_date_no_year: "D MMM" # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ - short_date: "D MMM, YYYY" + short_date: "D MMM YYYY" # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ - long_date: "MMMM D, YYYY h:mma" + long_date: "D MMMM YYYY LT" datetime_formats: &datetime_formats formats: - # Format directives: https://ruby-doc.org/core-2.6.1/Time.html#method-i-strftime - short: "%m-%d-%Y" - # Format directives: https://ruby-doc.org/core-2.6.1/Time.html#method-i-strftime - short_no_year: "%B %-d" - # Format directives: https://ruby-doc.org/core-2.6.1/Time.html#method-i-strftime - date_only: "%B %-d, %Y" - # Format directives: https://ruby-doc.org/core-2.6.1/Time.html#method-i-strftime - long: "%B %-d, %Y, %l:%M%P" - # Format directives: https://ruby-doc.org/core-2.6.1/Time.html#method-i-strftime + # Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime + short: "%d-%m-%Y" + # Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime + short_no_year: "%-d %B" + # Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime + date_only: "%-d %B %Y" + # Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime + long: "%-d %B %Y %H:%M" + # Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime no_day: "%B %Y" date: # Do not remove the brackets and commas and do not translate the first month name. It should be "null". @@ -1710,6 +1710,7 @@ en: max_image_megapixels: "Maximum number of megapixels allowed for an image." title_prettify: "Prevent common title typos and errors, including all caps, lowercase first character, multiple ! and ?, extra . at end, etc." + title_remove_extraneous_space: "Remove leading whitespaces in front of the end punctiation." topic_views_heat_low: "After this many views, the views field is slightly highlighted." topic_views_heat_medium: "After this many views, the views field is moderately highlighted." diff --git a/config/locales/server.en_US.yml b/config/locales/server.en_US.yml new file mode 100644 index 00000000000..3b4512908bb --- /dev/null +++ b/config/locales/server.en_US.yml @@ -0,0 +1,25 @@ +en_US: + dates: + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + short_date_no_year: "D MMM" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + short_date: "D MMM, YYYY" + # Use Moment.js format string: https://momentjs.com/docs/#/displaying/format/ + long_date: "MMMM D, YYYY h:mma" + + datetime_formats: &datetime_formats + formats: + # Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime + short: "%m-%d-%Y" + # Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime + short_no_year: "%B %-d" + # Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime + date_only: "%B %-d, %Y" + # Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime + long: "%B %-d, %Y, %l:%M%P" + # Format directives: https://ruby-doc.org/core/Time.html#method-i-strftime + no_day: "%B %Y" + date: + <<: *datetime_formats + time: + <<: *datetime_formats diff --git a/config/site_settings.yml b/config/site_settings.yml index a690f16c4cb..b82d9fb12c5 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -639,6 +639,11 @@ posting: ja: false zh_CN: false zh_TW: false + title_remove_extraneous_space: + default: false + locale_default: + en: true + en_US: true title_fancy_entities: true min_personal_message_title_length: client: true diff --git a/db/migrate/20190430135846_migrate_english_locale.rb b/db/migrate/20190430135846_migrate_english_locale.rb new file mode 100644 index 00000000000..c10222f67e4 --- /dev/null +++ b/db/migrate/20190430135846_migrate_english_locale.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +class MigrateEnglishLocale < ActiveRecord::Migration[5.2] + def up + execute <<~SQL + UPDATE users + SET locale = 'en_US' + WHERE locale = 'en' + SQL + + execute <<~SQL + UPDATE site_settings + SET value = 'en_US' + WHERE name = 'default_locale' AND value = 'en' + SQL + + execute <<~SQL + UPDATE translation_overrides + SET locale = 'en_US' + WHERE locale = 'en' + SQL + + execute <<~SQL + UPDATE theme_translation_overrides + SET locale = 'en_US' + WHERE locale = 'en' + SQL + end + + def down + execute <<~SQL + UPDATE users + SET locale = 'en' + WHERE locale = 'en_US' + SQL + + execute <<~SQL + UPDATE site_settings + SET value = 'en' + WHERE name = 'default_locale' AND value = 'en_US' + SQL + + execute <<~SQL + UPDATE translation_overrides + SET locale = 'en' + WHERE locale = 'en_US' + SQL + + execute <<~SQL + UPDATE theme_translation_overrides + SET locale = 'en' + WHERE locale = 'en_US' + SQL + end +end diff --git a/lib/js_locale_helper.rb b/lib/js_locale_helper.rb index 71b0eecd00a..9856766b9c0 100644 --- a/lib/js_locale_helper.rb +++ b/lib/js_locale_helper.rb @@ -127,8 +127,7 @@ module JsLocaleHelper fallback_locale_str = LocaleSiteSetting.fallback_locale(locale_str)&.to_s translations = Marshal.load(Marshal.dump(translations_for(locale_str))) - message_formats = strip_out_message_formats!(translations[locale_str]['js']) - message_formats.merge!(strip_out_message_formats!(translations[locale_str]['admin_js'])) + message_formats = remove_message_formats!(translations, locale) mf_locale, mf_filename = find_message_format_locale([locale_str], fallback_to_english: true) result = generate_message_format(message_formats, mf_locale, mf_filename) @@ -155,7 +154,8 @@ module JsLocaleHelper end MOMENT_LOCALE_MAPPING ||= { - "hy" => "hy-am" + "hy" => "hy-am", + "en" => "en-gb" } def self.find_moment_locale(locale_chain, timezone_names: false) @@ -259,18 +259,33 @@ module JsLocaleHelper "function(){ return #{message.inspect};}" end - def self.strip_out_message_formats!(hash, prefix = "", rval = {}) + def self.remove_message_formats!(translations, locale) + message_formats = {} + I18n.fallbacks[locale].map(&:to_s).each do |l| + next unless translations.key?(l) + + %w{js admin_js}.each do |k| + message_formats.merge!(strip_out_message_formats!(translations[l][k])) + end + end + message_formats + end + + def self.strip_out_message_formats!(hash, prefix = "", message_formats = {}) if hash.is_a?(Hash) hash.each do |key, value| if value.is_a?(Hash) - rval.merge!(strip_out_message_formats!(value, prefix + (prefix.length > 0 ? "." : "") << key, rval)) + message_formats.merge!(strip_out_message_formats!(value, join_key(prefix, key), message_formats)) elsif key.to_s.end_with?("_MF") - rval[prefix + (prefix.length > 0 ? "." : "") << key] = value + message_formats[join_key(prefix, key)] = value hash.delete(key) end end end - rval + message_formats end + def self.join_key(prefix, key) + prefix.blank? ? key : "#{prefix}.#{key}" + end end diff --git a/lib/site_settings/defaults_provider.rb b/lib/site_settings/defaults_provider.rb index 9ebae9aa512..1a4ac02a837 100644 --- a/lib/site_settings/defaults_provider.rb +++ b/lib/site_settings/defaults_provider.rb @@ -4,7 +4,7 @@ module SiteSettings; end # A cache for providing default value based on site locale class SiteSettings::DefaultsProvider - DEFAULT_LOCALE = 'en' + DEFAULT_LOCALE = 'en_US' def initialize(site_setting) @site_setting = site_setting diff --git a/lib/text_cleaner.rb b/lib/text_cleaner.rb index fa136a4984d..179ec5f70d9 100644 --- a/lib/text_cleaner.rb +++ b/lib/text_cleaner.rb @@ -17,7 +17,7 @@ class TextCleaner replace_all_upper_case: SiteSetting.title_prettify && !SiteSetting.allow_uppercase_posts, capitalize_first_letter: SiteSetting.title_prettify, remove_all_periods_from_the_end: SiteSetting.title_prettify, - remove_extraneous_space: SiteSetting.title_prettify && SiteSetting.default_locale == "en", + remove_extraneous_space: SiteSetting.title_prettify && SiteSetting.title_remove_extraneous_space, fixes_interior_spaces: true, strip_whitespaces: true, strip_zero_width_spaces: true diff --git a/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/quote_generator.rb b/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/quote_generator.rb index 7e1c5c6e62e..8934547687c 100644 --- a/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/quote_generator.rb +++ b/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/quote_generator.rb @@ -8,7 +8,7 @@ module DiscourseNarrativeBot def self.generate(user) quote, author = - if user.effective_locale != 'en' + if !user.effective_locale.start_with?('en') translation_key = "discourse_narrative_bot.quote.#{rand(1..10)}" [ diff --git a/script/bulk_import/base.rb b/script/bulk_import/base.rb index ea511edcd4e..3951f358024 100644 --- a/script/bulk_import/base.rb +++ b/script/bulk_import/base.rb @@ -105,7 +105,7 @@ class BulkImport::Base def preload_i18n puts "Preloading I18n..." - I18n.locale = ENV.fetch("LOCALE") { "en" }.to_sym + I18n.locale = ENV.fetch("LOCALE") { SiteSettings::DefaultsProvider::DEFAULT_LOCALE }.to_sym I18n.t("test") ActiveSupport::Inflector.transliterate("test") end diff --git a/script/pull_translations.rb b/script/pull_translations.rb index a4440123e79..921da2772cb 100755 --- a/script/pull_translations.rb +++ b/script/pull_translations.rb @@ -16,7 +16,7 @@ end def supported_locales Dir.glob(expand_path('config/locales/client.*.yml')) .map { |x| x.split('.')[-2] } - .select { |x| x != 'en' } + .reject { |x| x.start_with?('en') } .sort - TranslationsManager::BROKEN_LOCALES end diff --git a/spec/components/freedom_patches/translate_accelerator_spec.rb b/spec/components/freedom_patches/translate_accelerator_spec.rb index af2b60b5c03..9e3de035853 100644 --- a/spec/components/freedom_patches/translate_accelerator_spec.rb +++ b/spec/components/freedom_patches/translate_accelerator_spec.rb @@ -89,6 +89,8 @@ describe "translate accelerator" do end describe "with overrides" do + before { I18n.locale = :en } + it "returns the overridden key" do override_translation('en', 'foo', 'Overwritten foo') expect(I18n.t('foo')).to eq('Overwritten foo') diff --git a/spec/components/js_locale_helper_spec.rb b/spec/components/js_locale_helper_spec.rb index 2a5b18365fb..90d36a902a7 100644 --- a/spec/components/js_locale_helper_spec.rb +++ b/spec/components/js_locale_helper_spec.rb @@ -20,7 +20,6 @@ describe JsLocaleHelper do JsLocaleHelper.extend StubLoadTranslations after do - I18n.locale = :en JsLocaleHelper.clear_cache! end @@ -119,6 +118,16 @@ describe JsLocaleHelper do message = JsLocaleHelper.compile_message_format(message_format_filename('ru'), 'ru', 'format') expect(message).not_to match 'Plural Function not found' end + + it "includes uses message formats from fallback locale" do + translations = JsLocaleHelper.translations_for(:en_US) + en_us_message_formats = JsLocaleHelper.remove_message_formats!(translations, :en_US) + expect(en_us_message_formats).to_not be_empty + + translations = JsLocaleHelper.translations_for(:en) + en_message_formats = JsLocaleHelper.remove_message_formats!(translations, :en) + expect(en_us_message_formats).to eq(en_message_formats) + end end it 'performs fallbacks to english if a translation is not available' do @@ -190,7 +199,7 @@ describe JsLocaleHelper do it "finds moment.js locale file for #{locale[:value]}" do content = JsLocaleHelper.moment_locale(locale[:value]) - if (locale[:value] == 'en') + if (locale[:value] == SiteSettings::DefaultsProvider::DEFAULT_LOCALE) expect(content).to eq('') else expect(content).to_not eq('') diff --git a/spec/components/site_setting_extension_spec.rb b/spec/components/site_setting_extension_spec.rb index 766048d6b1b..9b225f0b699 100644 --- a/spec/components/site_setting_extension_spec.rb +++ b/spec/components/site_setting_extension_spec.rb @@ -766,7 +766,7 @@ describe SiteSettingExtension do describe '.default_locale' do it 'is always loaded' do - expect(settings.default_locale).to eq 'en' + expect(settings.default_locale).to eq('en_US') end end @@ -833,7 +833,7 @@ describe SiteSettingExtension do settings.refresh! expect(settings.client_settings_json_uncached).to eq( - %Q|{"default_locale":"en","upload_type":"#{upload.url}","string_type":"haha"}| + %Q|{"default_locale":"#{SiteSetting.default_locale}","upload_type":"#{upload.url}","string_type":"haha"}| ) end end diff --git a/spec/components/text_cleaner_spec.rb b/spec/components/text_cleaner_spec.rb index 4d01c35038c..f5293991706 100644 --- a/spec/components/text_cleaner_spec.rb +++ b/spec/components/text_cleaner_spec.rb @@ -196,7 +196,11 @@ describe TextCleaner do end it "removes extraneous space before the end punctuation" do + SiteSetting.title_remove_extraneous_space = true expect(TextCleaner.clean_title("Hello there ?")).to eq("Hello there?") + + SiteSetting.title_remove_extraneous_space = false + expect(TextCleaner.clean_title("Hello there ?")).to eq("Hello there ?") end it "replaces all upper case unicode text with regular unicode case letters" do diff --git a/spec/components/theme_store/tgz_exporter_spec.rb b/spec/components/theme_store/tgz_exporter_spec.rb index 5c3d08ec670..b66bf6e1b08 100644 --- a/spec/components/theme_store/tgz_exporter_spec.rb +++ b/spec/components/theme_store/tgz_exporter_spec.rb @@ -109,7 +109,7 @@ describe ThemeStore::TgzExporter do # Theme field names should be sanitized before writing to the database, # but protection is in place 'just in case' expect do - theme.set_field(target: :translations, name: "en", value: "hacked") + theme.set_field(target: :translations, name: SiteSetting.default_locale, value: "hacked") ThemeField.any_instance.stubs(:file_path).returns("../../malicious") theme.save! package diff --git a/spec/components/wizard/step_updater_spec.rb b/spec/components/wizard/step_updater_spec.rb index cc333267025..ef43bb8f191 100644 --- a/spec/components/wizard/step_updater_spec.rb +++ b/spec/components/wizard/step_updater_spec.rb @@ -15,7 +15,8 @@ describe Wizard::StepUpdater do context "locale" do it "does not require refresh when the language stays the same" do - updater = wizard.create_updater('locale', default_locale: 'en') + locale = SiteSettings::DefaultsProvider::DEFAULT_LOCALE + updater = wizard.create_updater('locale', default_locale: locale) updater.update expect(updater.refresh_required?).to eq(false) expect(wizard.completed_steps?('locale')).to eq(true) diff --git a/spec/integrity/i18n_spec.rb b/spec/integrity/i18n_spec.rb index 4866ad2beac..097bec2d1ac 100644 --- a/spec/integrity/i18n_spec.rb +++ b/spec/integrity/i18n_spec.rb @@ -90,8 +90,11 @@ describe "i18n integrity checks" do expect(yaml.keys).to eq([locale]) expect(yaml[locale]["js"]).to be - expect(yaml[locale]["admin_js"]).to be - # expect(yaml[locale]["wizard_js"]).to be + + if !LocaleSiteSetting.fallback_locale(locale) + expect(yaml[locale]["admin_js"]).to be + expect(yaml[locale]["wizard_js"]).to be + end end end diff --git a/spec/components/discourse_i18n_spec.rb b/spec/lib/i18n/discourse_i18n_spec.rb similarity index 100% rename from spec/components/discourse_i18n_spec.rb rename to spec/lib/i18n/discourse_i18n_spec.rb diff --git a/spec/components/fallback_locale_list_spec.rb b/spec/lib/i18n/fallback_locale_list_spec.rb similarity index 84% rename from spec/components/fallback_locale_list_spec.rb rename to spec/lib/i18n/fallback_locale_list_spec.rb index 718dd8fde56..004ebfc0e59 100644 --- a/spec/components/fallback_locale_list_spec.rb +++ b/spec/lib/i18n/fallback_locale_list_spec.rb @@ -13,6 +13,14 @@ describe I18n::Backend::FallbackLocaleList do expect(list[:en]).to eq([:en]) end + it "works when default_locale is English (United States)" do + SiteSetting.default_locale = :en_US + + expect(list[:ru]).to eq([:ru, :en_US, :en]) + expect(list[:en_US]).to eq([:en_US, :en]) + expect(list[:en]).to eq([:en]) + end + it "works when default_locale is not English" do SiteSetting.default_locale = :de diff --git a/spec/services/i18n_interpolation_keys_finder_spec.rb b/spec/lib/i18n/i18n_interpolation_keys_finder_spec.rb similarity index 100% rename from spec/services/i18n_interpolation_keys_finder_spec.rb rename to spec/lib/i18n/i18n_interpolation_keys_finder_spec.rb diff --git a/spec/mailers/user_notifications_spec.rb b/spec/mailers/user_notifications_spec.rb index e10b04e5e21..7106d4641f2 100644 --- a/spec/mailers/user_notifications_spec.rb +++ b/spec/mailers/user_notifications_spec.rb @@ -787,7 +787,7 @@ describe UserNotifications do before do TranslationOverride.upsert!( - "en", + SiteSetting.default_locale, "#{mail_template}.text_body_template", custom_body ) @@ -901,7 +901,6 @@ describe UserNotifications do context "user locale is allowed" do before do - SiteSetting.default_locale = "en" SiteSetting.allow_user_locale = true end @@ -919,7 +918,6 @@ describe UserNotifications do context "user locale is not allowed" do before do - SiteSetting.default_locale = "en" SiteSetting.allow_user_locale = false end @@ -929,7 +927,7 @@ describe UserNotifications do let(:locale) { "fr" } let(:mail_type) { mail_type } it "sets the locale" do - expects_build_with(has_entry(:locale, "en")) + expects_build_with(has_entry(:locale, "en_US")) end end end diff --git a/spec/models/badge_spec.rb b/spec/models/badge_spec.rb index eecd44ad188..81e136cad1c 100644 --- a/spec/models/badge_spec.rb +++ b/spec/models/badge_spec.rb @@ -20,12 +20,8 @@ describe Badge do badge = Badge.find_by_name("Basic User") name_english = badge.name - begin - I18n.locale = 'fr' - + I18n.with_locale(:fr) do expect(badge.display_name).not_to eq(name_english) - ensure - I18n.locale = :en end end diff --git a/spec/models/locale_site_setting_spec.rb b/spec/models/locale_site_setting_spec.rb index 947ee5e5cec..1addea5c94b 100644 --- a/spec/models/locale_site_setting_spec.rb +++ b/spec/models/locale_site_setting_spec.rb @@ -13,7 +13,7 @@ describe LocaleSiteSetting do value[:name] end - describe 'valid_value?' do + describe '.valid_value?' do it 'returns true for a locale that we have translations for' do expect(LocaleSiteSetting.valid_value?('en')).to eq(true) end @@ -23,7 +23,7 @@ describe LocaleSiteSetting do end end - describe 'values' do + describe '.values' do it 'returns all the locales that we have translations for' do expect(LocaleSiteSetting.values.map { |x| x[:value] }).to include(*core_locales) end @@ -52,7 +52,7 @@ describe LocaleSiteSetting do DiscoursePluginRegistry.reset! end - describe 'valid_value?' do + describe '.valid_value?' do it 'returns true for locales from core' do expect(LocaleSiteSetting.valid_value?('en')).to eq(true) expect(LocaleSiteSetting.valid_value?('de')).to eq(true) @@ -64,7 +64,7 @@ describe LocaleSiteSetting do end end - describe 'values' do + describe '.values' do it 'returns native names added by plugin' do expect(native_locale_name('foo')).to eq('Native Foo') expect(native_locale_name('bar')).to eq('Native Bar') @@ -79,7 +79,7 @@ describe LocaleSiteSetting do end end - describe 'fallback_locale' do + describe '.fallback_locale' do it 'returns the fallback locale registered by plugin' do expect(LocaleSiteSetting.fallback_locale('de_AT')).to eq(:de) expect(LocaleSiteSetting.fallback_locale(:de_AT)).to eq(:de) @@ -88,6 +88,16 @@ describe LocaleSiteSetting do it 'returns nothing when no fallback locale was registered' do expect(LocaleSiteSetting.fallback_locale('foo')).to be_nil end + + it 'returns English for English (United States)' do + expect(LocaleSiteSetting.fallback_locale('en_US')).to eq(:en) + end + end + end + + describe '.fallback_locale' do + it 'returns English for English (United States)' do + expect(LocaleSiteSetting.fallback_locale('en_US')).to eq(:en) end end end diff --git a/spec/models/theme_field_spec.rb b/spec/models/theme_field_spec.rb index 3b8c93f2343..e7489a1dc26 100644 --- a/spec/models/theme_field_spec.rb +++ b/spec/models/theme_field_spec.rb @@ -239,8 +239,8 @@ HTML let!(:theme3) { Fabricate(:theme) } let!(:en1) { - ThemeField.create!(theme: theme, target_id: Theme.targets[:translations], name: "en", - value: { en: { somestring1: "helloworld", group: { key1: "enval1" } } } + ThemeField.create!(theme: theme, target_id: Theme.targets[:translations], name: "en_US", + value: { en_US: { somestring1: "helloworld", group: { key1: "enval1" } } } .deep_stringify_keys.to_yaml ) } @@ -251,21 +251,21 @@ HTML ) } let!(:fr2) { ThemeField.create!(theme: theme2, target_id: Theme.targets[:translations], name: "fr", value: "") } - let!(:en2) { ThemeField.create!(theme: theme2, target_id: Theme.targets[:translations], name: "en", value: "") } + let!(:en2) { ThemeField.create!(theme: theme2, target_id: Theme.targets[:translations], name: "en_US", value: "") } let!(:ca3) { ThemeField.create!(theme: theme3, target_id: Theme.targets[:translations], name: "ca", value: "") } - let!(:en3) { ThemeField.create!(theme: theme3, target_id: Theme.targets[:translations], name: "en", value: "") } + let!(:en3) { ThemeField.create!(theme: theme3, target_id: Theme.targets[:translations], name: "en_US", value: "") } describe "scopes" do it "filter_locale_fields returns results in the correct order" do expect(ThemeField.find_by_theme_ids([theme3.id, theme.id, theme2.id]) .filter_locale_fields( - ["en", "fr"] + ["en_US", "fr"] )).to eq([en3, en1, fr1, en2, fr2]) end it "find_first_locale_fields returns only the first locale for each theme" do expect(ThemeField.find_first_locale_fields( - [theme3.id, theme.id, theme2.id], ["ca", "en", "fr"] + [theme3.id, theme.id, theme2.id], ["ca", "en_US", "fr"] )).to eq([ca3, en1, en2]) end end @@ -296,7 +296,7 @@ HTML it "loads correctly" do expect(fr1.translation_data).to eq( fr: { somestring1: "bonjourworld", group: { key2: "frval2" } }, - en: { somestring1: "helloworld", group: { key1: "enval1" } } + en_US: { somestring1: "helloworld", group: { key1: "enval1" } } ) end @@ -318,7 +318,7 @@ HTML theme.reload expect(fr1.translation_data).to eq( fr: { somestring1: "bonjourworld", group: { key2: "frval2" } }, - en: { somestring1: "helloworld", group: { key1: "overriddentest1" } } + en_US: { somestring1: "helloworld", group: { key1: "overriddentest1" } } ) end end diff --git a/spec/models/theme_spec.rb b/spec/models/theme_spec.rb index d145540ae6e..2a6767d4275 100644 --- a/spec/models/theme_spec.rb +++ b/spec/models/theme_spec.rb @@ -599,8 +599,8 @@ HTML end it "can create a hash of overridden values" do - en_translation = ThemeField.create!(theme_id: theme.id, name: "en", type_id: ThemeField.types[:yaml], target_id: Theme.targets[:translations], value: <<~YAML) - en: + en_translation = ThemeField.create!(theme_id: theme.id, name: "en_US", type_id: ThemeField.types[:yaml], target_id: Theme.targets[:translations], value: <<~YAML) + en_US: group_of_translations: translation1: en test1 YAML @@ -610,7 +610,7 @@ HTML theme.update_translation("group_of_translations.translation1", "overriddentest2") theme.reload expect(theme.translation_override_hash).to eq( - "en" => { + "en_US" => { "group_of_translations" => { "translation1" => "overriddentest1" } diff --git a/spec/models/translation_override_spec.rb b/spec/models/translation_override_spec.rb index 7b122e45674..cbbf1d8a873 100644 --- a/spec/models/translation_override_spec.rb +++ b/spec/models/translation_override_spec.rb @@ -6,7 +6,7 @@ describe TranslationOverride do context 'validations' do describe '#value' do before do - I18n.backend.store_translations(:en, some_key: '%{first} %{second}') + I18n.backend.store_translations(I18n.locale, some_key: '%{first} %{second}') end describe 'when interpolation keys are missing' do diff --git a/spec/multisite/site_settings_spec.rb b/spec/multisite/site_settings_spec.rb index 069c2663524..ba0d971bc2f 100644 --- a/spec/multisite/site_settings_spec.rb +++ b/spec/multisite/site_settings_spec.rb @@ -15,7 +15,7 @@ RSpec.describe 'Multisite SiteSettings', type: :multisite do describe '#default_locale' do it 'should return the right locale' do test_multisite_connection('default') do - expect(SiteSetting.default_locale).to eq('en') + expect(SiteSetting.default_locale).to eq('en_US') end test_multisite_connection('second') do @@ -25,7 +25,7 @@ RSpec.describe 'Multisite SiteSettings', type: :multisite do end test_multisite_connection('default') do - expect(SiteSetting.default_locale).to eq('en') + expect(SiteSetting.default_locale).to eq('en_US') SiteSetting.default_locale = 'ja' diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 3d5a92dd5b0..6153b9e0f1e 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -108,7 +108,7 @@ module TestSetup Discourse.clear_readonly! Sidekiq::Worker.clear_all - I18n.locale = :en + I18n.locale = SiteSettings::DefaultsProvider::DEFAULT_LOCALE RspecErrorTracker.last_exception = nil diff --git a/spec/requests/admin/site_texts_controller_spec.rb b/spec/requests/admin/site_texts_controller_spec.rb index 234129a0e65..006476b457a 100644 --- a/spec/requests/admin/site_texts_controller_spec.rb +++ b/spec/requests/admin/site_texts_controller_spec.rb @@ -271,7 +271,7 @@ RSpec.describe Admin::SiteTextsController do end it "returns the right error message" do - I18n.backend.store_translations(:en, some_key: '%{first} %{second}') + I18n.backend.store_translations(SiteSetting.default_locale, some_key: '%{first} %{second}') put "/admin/customize/site_texts/some_key.json", params: { site_text: { value: 'hello %{key} %{omg}' } diff --git a/spec/requests/extra_locales_controller_spec.rb b/spec/requests/extra_locales_controller_spec.rb index a20c49e7428..bd472272e44 100644 --- a/spec/requests/extra_locales_controller_spec.rb +++ b/spec/requests/extra_locales_controller_spec.rb @@ -27,11 +27,8 @@ describe ExtraLocalesController do end it "includes plugin translations" do - I18n.locale = :en - I18n.reload! - JsLocaleHelper.expects(:plugin_translations) - .with(I18n.locale.to_s) + .with(any_of("en", "en_US")) .returns("admin_js" => { "admin" => { "site_settings" => { diff --git a/spec/services/search_indexer_spec.rb b/spec/services/search_indexer_spec.rb index b9be8c2fb3b..b92f342945e 100644 --- a/spec/services/search_indexer_spec.rb +++ b/spec/services/search_indexer_spec.rb @@ -102,7 +102,7 @@ describe SearchIndexer do raw_data, locale, version = PostSearchData.where(post_id: post_id).pluck(:raw_data, :locale, :version)[0] expect(raw_data).to eq("This is a test") - expect(locale).to eq("en") + expect(locale).to eq(SiteSetting.default_locale) expect(version).to eq(SearchIndexer::INDEX_VERSION) SearchIndexer.update_posts_index(post_id, "tester", "", nil, nil) diff --git a/test/javascripts/components/d-editor-test.js.es6 b/test/javascripts/components/d-editor-test.js.es6 index efec8ba0cb6..58ba1f5a4f8 100644 --- a/test/javascripts/components/d-editor-test.js.es6 +++ b/test/javascripts/components/d-editor-test.js.es6 @@ -646,7 +646,7 @@ componentTest("clicking the toggle-direction button toggles the direction", { template: "{{d-editor value=value}}", beforeEach() { this.siteSettings.support_mixed_text_direction = true; - this.siteSettings.default_locale = "en"; + this.siteSettings.default_locale = "en_US"; }, async test(assert) { diff --git a/test/javascripts/fixtures/about.js.es6 b/test/javascripts/fixtures/about.js.es6 index cf428e03e68..2c17392c68c 100644 --- a/test/javascripts/fixtures/about.js.es6 +++ b/test/javascripts/fixtures/about.js.es6 @@ -20,7 +20,7 @@ export default { description: "Discussion about the next-generation open source Discourse forum software", title: "Discourse Meta", - locale: "en", + locale: "en_US", version: "2.2.0.beta8", https: true, admins: [ diff --git a/test/javascripts/test_helper.js b/test/javascripts/test_helper.js index dfd5d08d3da..67a429395e7 100644 --- a/test/javascripts/test_helper.js +++ b/test/javascripts/test_helper.js @@ -16,7 +16,7 @@ //= require preload-store //= require locales/i18n -//= require locales/en +//= require locales/en_US // Stuff we need to load first //= require vendor