Skip to content

Commit 5909f4c

Browse files
committed
DEV: Move language detection out of the post serializer
Language detection is added to the queue every time the post is serialized, move this into the post_created and post_edited events instead.
1 parent c13c494 commit 5909f4c

File tree

5 files changed

+111
-71
lines changed

5 files changed

+111
-71
lines changed

lib/discourse_translator/guardian_extension.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,11 @@ def poster_group_allow_translate?(post)
1111
return false if post.user.nil?
1212
post.user.in_any_groups?(SiteSetting.restrict_translation_by_poster_group_map)
1313
end
14+
15+
def can_detect_language?(post)
16+
(
17+
SiteSetting.restrict_translation_by_poster_group_map.empty? ||
18+
post&.user&.in_any_groups?(SiteSetting.restrict_translation_by_poster_group_map)
19+
) && post.raw.present? && post.post_type != Post.types[:small_action]
20+
end
1421
end

plugin.rb

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,20 @@ module ::DiscourseTranslator
3737
Topic.prepend(DiscourseTranslator::TopicExtension)
3838
end
3939

40-
add_to_serializer :post, :can_translate do
41-
return false if !SiteSetting.translator_enabled
42-
if !scope.user_group_allow_translate? || !scope.poster_group_allow_translate?(object)
43-
return false
40+
on(:post_process_cooked) do |_, post|
41+
if Guardian.new.can_detect_language?(post)
42+
Discourse.redis.sadd?(DiscourseTranslator::LANG_DETECT_NEEDED, post.id)
4443
end
45-
return false if raw.blank? || post_type == Post.types[:small_action]
44+
end
4645

46+
add_to_serializer :post, :can_translate do
4747
detected_lang = post_custom_fields[::DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD]
4848

49-
if !detected_lang
50-
Discourse.redis.sadd?(DiscourseTranslator::LANG_DETECT_NEEDED, object.id)
51-
false
52-
else
53-
detected_lang.to_sym != I18n.locale &&
54-
"DiscourseTranslator::#{SiteSetting.translator}".constantize.language_supported?(
55-
detected_lang,
56-
)
57-
end
49+
return false if !scope.user_group_allow_translate? || !detected_lang
50+
51+
detected_lang.to_sym != I18n.locale &&
52+
"DiscourseTranslator::#{SiteSetting.translator}".constantize.language_supported?(
53+
detected_lang,
54+
)
5855
end
5956
end

spec/lib/guardian_extension_spec.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,40 @@
7777
end
7878
end
7979
end
80+
81+
describe "#can_detect_language?" do
82+
fab!(:group)
83+
fab!(:user) { Fabricate(:user, groups: [group]) }
84+
fab!(:post) { Fabricate(:post, user: user, raw: "Hello, world!") }
85+
let(:guardian) { Guardian.new(user) }
86+
87+
it "returns false when the post user is not in restrict_translation_by_poster_group" do
88+
SiteSetting.restrict_translation_by_poster_group = "#{group.id + 1}"
89+
90+
expect(guardian.can_detect_language?(post)).to eq(false)
91+
end
92+
93+
context "when post author is in allowed groups" do
94+
before do
95+
SiteSetting.restrict_translation_by_group = "#{group.id}"
96+
SiteSetting.restrict_translation_by_poster_group = "#{group.id}"
97+
end
98+
99+
it "returns true when the post is not a small action post" do
100+
expect(guardian.can_detect_language?(post)).to eq(true)
101+
end
102+
103+
it "returns false when the post is a small action post" do
104+
post.update(post_type: Post.types[:small_action])
105+
106+
expect(guardian.can_detect_language?(post)).to eq(false)
107+
end
108+
109+
it "returns false when the post raw is empty" do
110+
post.update(raw: "")
111+
112+
expect(guardian.can_detect_language?(post)).to eq(false)
113+
end
114+
end
115+
end
80116
end

spec/models/post_spec.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,33 @@
2727
expect(post.custom_fields[::DiscourseTranslator::TRANSLATED_CUSTOM_FIELD]).to be_nil
2828
end
2929
end
30+
31+
describe "queueing post for language detection" do
32+
fab!(:group)
33+
fab!(:topic)
34+
fab!(:user) { Fabricate(:user, groups: [group]) }
35+
36+
before do
37+
Jobs.run_immediately!
38+
SiteSetting.create_topic_allowed_groups = Group::AUTO_GROUPS[:everyone]
39+
end
40+
41+
it "queues the post for language detection when user and posts are in the right group" do
42+
SiteSetting.restrict_translation_by_poster_group = "#{group.id}"
43+
post = PostCreator.new(user, { title: "hello world topic", raw: "my name is fred", category: Fabricate(:category).id }).create
44+
45+
expect(Discourse.redis.sismember(DiscourseTranslator::LANG_DETECT_NEEDED, post.id)).to be_truthy
46+
end
47+
48+
context "when user and posts are not in the right group" do
49+
it "does not queue the post for language detection" do
50+
SiteSetting.restrict_translation_by_poster_group = "#{group.id + 1}"
51+
post = PostCreator.new(user, { title: "hello world topic", raw: "my name is fred", category: Fabricate(:category).id }).create
52+
53+
expect(
54+
Discourse.redis.sismember(DiscourseTranslator::LANG_DETECT_NEEDED, post.id),
55+
).to be_falsey
56+
end
57+
end
58+
end
3059
end

spec/serializers/post_serializer_spec.rb

Lines changed: 28 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,22 @@
1212

1313
describe "#can_translate" do
1414
it "returns false when translator disabled" do
15-
SiteSetting.translator_enabled = true
15+
SiteSetting.translator_enabled = false
1616
serializer = PostSerializer.new(post, scope: Guardian.new)
1717

1818
expect(serializer.can_translate).to eq(false)
1919
end
2020

2121
describe "when translator enabled" do
22-
before do
23-
SiteSetting.translator_enabled = true
24-
Jobs.run_later!
25-
end
22+
before { SiteSetting.translator_enabled = true }
2623

27-
describe "when small action post" do
28-
fab!(:small_action)
29-
let(:serializer) { PostSerializer.new(small_action, scope: Guardian.new) }
24+
describe "anon user" do
25+
let(:serializer) { PostSerializer.new(post, scope: Guardian.new) }
3026

31-
it "cannot translate" do
32-
expect(serializer.can_translate).to eq(false)
27+
before do
28+
SiteSetting.restrict_translation_by_group = "#{Group::AUTO_GROUPS[:everyone]}"
29+
SiteSetting.restrict_translation_by_poster_group = ""
3330
end
34-
end
35-
36-
describe "when post raw is empty" do
37-
fab!(:empty_post) do
38-
empty_post = Fabricate.build(:post, raw: "")
39-
empty_post.save!(validate: false)
40-
empty_post
41-
end
42-
let(:serializer) { PostSerializer.new(empty_post, scope: Guardian.new) }
4331

4432
it "cannot translate" do
4533
expect(serializer.can_translate).to eq(false)
@@ -49,61 +37,44 @@
4937
describe "logged in user" do
5038
let(:serializer) { PostSerializer.new(post, scope: Guardian.new(user)) }
5139

52-
describe "when user is not in restrict_translation_by_group" do
53-
it "cannot translate" do
54-
SiteSetting.restrict_translation_by_group = ""
40+
it "cannot translate when user is not in restrict_translation_by_group" do
41+
SiteSetting.restrict_translation_by_group = "#{group.id + 1}"
5542

56-
expect(serializer.can_translate).to eq(false)
57-
end
43+
expect(serializer.can_translate).to eq(false)
5844
end
5945

60-
describe "when post is not in restrict_translation_by_poster_group" do
61-
it "cannot translate" do
62-
SiteSetting.restrict_translation_by_group = "#{group.id}"
63-
SiteSetting.restrict_translation_by_poster_group = ""
46+
describe "user is in restrict_translation_by_group" do
47+
before { SiteSetting.restrict_translation_by_group = "#{group.id}" }
6448

65-
expect(serializer.can_translate).to eq(false)
66-
end
67-
end
49+
it "cannot translate when post author is not in restrict_translation_by_poster_group" do
50+
SiteSetting.restrict_translation_by_poster_group = "#{group.id}"
6851

69-
describe "when user is in restrict_translation_by_group and poster in restrict_translation_by_poster_group" do
70-
before do
71-
SiteSetting.restrict_translation_by_group = "#{group.id}"
72-
SiteSetting.restrict_translation_by_poster_group = "#{post_user_group.id}"
52+
expect(serializer.can_translate).to eq(false)
7353
end
7454

75-
describe "when post does not have DETECTED_LANG_CUSTOM_FIELD" do
76-
it "cannot translate" do
77-
expect(serializer.can_translate).to eq(false)
55+
describe "post author in restrict_translation_by_poster_group and locale is :xx" do
56+
before do
57+
SiteSetting.restrict_translation_by_poster_group = "#{post_user_group.id}"
58+
I18n.stubs(:locale).returns(:pt)
7859
end
7960

80-
it "adds post id to redis if detected_language is blank" do
81-
post.custom_fields["detected_language"] = nil
82-
post.save_custom_fields
83-
84-
expect { serializer.can_translate }.to change {
85-
Discourse.redis.sismember(DiscourseTranslator::LANG_DETECT_NEEDED, post.id)
86-
}.from(false).to(true)
61+
it "cannot translate when post does not have DETECTED_LANG_CUSTOM_FIELD" do
62+
expect(serializer.can_translate).to eq(false)
8763
end
88-
end
8964

90-
describe "when post has DETECTED_LANG_CUSTOM_FIELD matches user locale" do
91-
before do
92-
I18n.stubs(:locale).returns(:xx)
93-
post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] = "xx"
65+
it "cannot translate when post has DETECTED_LANG_CUSTOM_FIELD matches locale" do
66+
post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] = "pt"
9467
post.save
95-
end
9668

97-
it { expect(serializer.can_translate).to eq(false) }
98-
end
69+
expect(serializer.can_translate).to eq(false)
70+
end
9971

100-
describe "when post has DETECTED_LANG_CUSTOM_FIELD does not match user locale" do
101-
before do
72+
it "can translate when post has DETECTED_LANG_CUSTOM_FIELD does not match locale" do
10273
post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] = "jp"
10374
post.save
104-
end
10575

106-
it { expect(serializer.can_translate).to eq(true) }
76+
expect(serializer.can_translate).to eq(true)
77+
end
10778
end
10879
end
10980
end

0 commit comments

Comments
 (0)