From c4845acf5e0463da38bdcd6a4d77a0f7094bd150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guitaut?= Date: Wed, 24 Jul 2024 18:05:17 +0200 Subject: [PATCH] FIX: Allow invalid plural keys in MF translations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can get translations with invalid plural keys from Crowdin or from custom overrides. Currently, this will raise an error and the locales won’t be outputted at all. This patch addresses this issue by using the new `strict: false` option of our `messageformat-wrapper` gem, allowing to generate locales even if there are invalid plural keys present. --- Gemfile.lock | 2 +- lib/js_locale_helper.rb | 2 +- spec/lib/js_locale_helper_spec.rb | 44 ++++++++++++++++++++++++++----- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7a1913abeeb..940c2cf5b75 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -236,7 +236,7 @@ GEM memory_profiler (1.0.2) message_bus (4.3.8) rack (>= 1.1.3) - messageformat-wrapper (1.0.0) + messageformat-wrapper (1.1.0) mini_racer (>= 0.6.3) method_source (1.1.0) mini_mime (1.1.5) diff --git a/lib/js_locale_helper.rb b/lib/js_locale_helper.rb index cfb85f9ddc0..8b396707e1f 100644 --- a/lib/js_locale_helper.rb +++ b/lib/js_locale_helper.rb @@ -150,7 +150,7 @@ module JsLocaleHelper ) end .compact_blank - compiled = MessageFormat.compile(message_formats.keys, message_formats) + compiled = MessageFormat.compile(message_formats.keys, message_formats, strict: false) transpiled = DiscourseJsProcessor.transpile(<<~JS, "", "discourse-mf") import Messages from '@messageformat/runtime/messages'; #{compiled.sub("export default", "const msgData =")}; diff --git a/spec/lib/js_locale_helper_spec.rb b/spec/lib/js_locale_helper_spec.rb index 3a9198c2076..b918468f5cb 100644 --- a/spec/lib/js_locale_helper_spec.rb +++ b/spec/lib/js_locale_helper_spec.rb @@ -147,18 +147,34 @@ RSpec.describe JsLocaleHelper do end describe ".output_MF" do - let(:output) { described_class.output_MF(locale).gsub(/^import.*$/, "") } - let(:generated_locales) { v8_ctx.eval("Object.keys(I18n._mfMessages._data)") } - let(:translated_message) do - v8_ctx.eval("I18n._mfMessages.get('posts_likes_MF', {count: 3, ratio: 'med'})") - end - let!(:overriden_translation) do + fab!(:overriden_translation_en) do Fabricate( :translation_override, translation_key: "admin_js.admin.user.penalty_history_MF", value: "OVERRIDEN", ) end + fab!(:overriden_translation_ja) do + Fabricate( + :translation_override, + locale: "ja", + translation_key: "js.posts_likes_MF", + value: "{ count, plural, one {返信 # 件、} other {返信 # 件、} }", + ) + end + fab!(:overriden_translation_he) do + Fabricate( + :translation_override, + locale: "he", + translation_key: "js.posts_likes_MF", + value: "{ count, plural, ", + ) + end + let(:output) { described_class.output_MF(locale).gsub(/^import.*$/, "") } + let(:generated_locales) { v8_ctx.eval("Object.keys(I18n._mfMessages._data)") } + let(:translated_message) do + v8_ctx.eval("I18n._mfMessages.get('posts_likes_MF', {count: 3, ratio: 'med'})") + end before { v8_ctx.eval(output) } @@ -227,5 +243,21 @@ RSpec.describe JsLocaleHelper do end end end + + context "when locale contains invalid plural keys" do + let(:locale) { "ja" } + + it "does not raise an error" do + expect(generated_locales).to match(%w[ja en]) + end + end + + context "when locale contains malformed messages" do + let(:locale) { "he" } + + it "raises an error" do + expect(output).to match(/Failed to compile message formats/) + end + end end end