Skip to content

Commit 346d47c

Browse files
authored
FIX: Normalize languages within Discourse AI translator (#194)
The criteria to allow a post to be translated is if the user's locale is different from the site's default locale. For each translator (e.g. Google, Amazon, Azure), we maintain a list of mappings `SUPPORTED_LANG_MAPPING` for each locale. On top of that, this mapping is also used to define what language the post should be translated to. When using most translators available in the plugin, "en_GB" forums will translate text to "en" due to these mappings. This is not a problem for Discourse AI provider, since there are no restrictions on language. This PR normalizes locales within Discourse AI translator, so that it sees "ar" to be the same as "ar_SA".
1 parent c89a85a commit 346d47c

File tree

5 files changed

+88
-12
lines changed

5 files changed

+88
-12
lines changed

app/services/discourse_translator/discourse_ai.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
module DiscourseTranslator
77
class DiscourseAi < Base
88
MAX_DETECT_LOCALE_TEXT_LENGTH = 1000
9-
def self.language_supported?(_)
10-
true
9+
def self.language_supported?(detected_lang)
10+
locale_without_region = I18n.locale.to_s.split("_").first
11+
detected_lang != locale_without_region
1112
end
1213

1314
def self.detect(topic_or_post)

lib/discourse_translator/guardian_extension.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,21 @@ def can_detect_language?(post)
1818
post&.user&.in_any_groups?(SiteSetting.restrict_translation_by_poster_group_map)
1919
) && post.raw.present? && post.post_type != Post.types[:small_action]
2020
end
21+
22+
def can_translate?(post)
23+
return false if !user_group_allow_translate?
24+
25+
# we will deal with regionalized_strings (not syms) when comparing locales
26+
# e.g. "en_GB"
27+
# not "en-GB"
28+
# nor :en_GB (I18n.locale)
29+
detected_lang =
30+
post.custom_fields[::DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD].to_s.sub("-", "_")
31+
return false if detected_lang.blank?
32+
33+
detected_lang != I18n.locale.to_s &&
34+
"DiscourseTranslator::#{SiteSetting.translator}".constantize.language_supported?(
35+
detected_lang,
36+
)
37+
end
2138
end

plugin.rb

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,6 @@ module ::DiscourseTranslator
4444
end
4545

4646
add_to_serializer :post, :can_translate do
47-
return false if !scope.user_group_allow_translate?
48-
49-
detected_lang = post_custom_fields[::DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD]
50-
return false if detected_lang.blank?
51-
52-
detected_lang.to_sym != I18n.locale &&
53-
"DiscourseTranslator::#{SiteSetting.translator}".constantize.language_supported?(
54-
detected_lang,
55-
)
47+
scope.can_translate?(object)
5648
end
5749
end

spec/lib/guardian_extension_spec.rb

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,64 @@
113113
end
114114
end
115115
end
116+
117+
describe "#can_translate?" do
118+
fab!(:group)
119+
fab!(:user) { Fabricate(:user, locale: "en", groups: [group]) }
120+
fab!(:post)
121+
122+
let(:guardian) { Guardian.new(user) }
123+
124+
it "returns false when translator disabled" do
125+
SiteSetting.translator_enabled = false
126+
127+
expect(guardian.can_translate?(post)).to eq(false)
128+
end
129+
130+
describe "when translator enabled" do
131+
before { SiteSetting.translator_enabled = true }
132+
133+
describe "anon user" do
134+
before { SiteSetting.restrict_translation_by_group = "#{Group::AUTO_GROUPS[:everyone]}" }
135+
136+
it "cannot translate" do
137+
expect(Guardian.new.can_translate?(post)).to eq(false)
138+
end
139+
end
140+
141+
describe "logged in user" do
142+
it "cannot translate when user is not in restrict_translation_by_group" do
143+
SiteSetting.restrict_translation_by_group = "#{group.id + 1}"
144+
145+
expect(guardian.can_translate?(post)).to eq(false)
146+
end
147+
148+
describe "user is in restrict_translation_by_group" do
149+
before { SiteSetting.restrict_translation_by_group = "#{group.id}" }
150+
151+
describe "locale is :xx" do
152+
before { I18n.stubs(:locale).returns(:pt) }
153+
154+
it "cannot translate when post does not have DETECTED_LANG_CUSTOM_FIELD" do
155+
expect(guardian.can_translate?(post)).to eq(false)
156+
end
157+
158+
it "cannot translate when post has DETECTED_LANG_CUSTOM_FIELD matches locale" do
159+
post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] = "pt"
160+
post.save
161+
162+
expect(guardian.can_translate?(post)).to eq(false)
163+
end
164+
165+
it "can translate when post has DETECTED_LANG_CUSTOM_FIELD does not match locale" do
166+
post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] = "jp"
167+
post.save
168+
169+
expect(guardian.can_translate?(post)).to eq(true)
170+
end
171+
end
172+
end
173+
end
174+
end
175+
end
116176
end

spec/services/discourse_ai_spec.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,15 @@
1515
end
1616

1717
describe ".language_supported?" do
18-
it "returns true for any language" do
18+
it "returns true when detected language is different from i18n locale" do
19+
I18n.stubs(:locale).returns(:xx)
1920
expect(described_class.language_supported?("any-language")).to eq(true)
2021
end
22+
23+
it "returns false when detected language is same base language as i18n locale" do
24+
I18n.stubs(:locale).returns(:en_GB)
25+
expect(described_class.language_supported?("en")).to eq(false)
26+
end
2127
end
2228

2329
describe ".detect" do

0 commit comments

Comments
 (0)