Skip to content

Commit 4d53c8c

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 4d53c8c

File tree

5 files changed

+127
-66
lines changed

5 files changed

+127
-66
lines changed

lib/discourse_translator/guardian_extension.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,9 @@ 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+
poster_group_allow_translate?(post) && post.raw.present? &&
17+
post.post_type != Post.types[:small_action]
18+
end
1419
end

plugin.rb

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,28 @@ 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_created) do |post, _, user|
41+
if Guardian.new(user).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+
on(:post_edited) do |post, _, user|
47+
if Guardian.new(user).can_detect_language?(post)
48+
Discourse.redis.sadd?(DiscourseTranslator::LANG_DETECT_NEEDED, post.id)
49+
end
50+
end
51+
52+
add_to_serializer :post, :can_translate do
4753
detected_lang = post_custom_fields[::DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD]
4854

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-
)
55+
if !scope.user_group_allow_translate? || !detected_lang
56+
return false
5757
end
58+
59+
detected_lang.to_sym != I18n.locale &&
60+
"DiscourseTranslator::#{SiteSetting.translator}".constantize.language_supported?(
61+
detected_lang,
62+
)
5863
end
5964
end

spec/lib/guardian_extension_spec.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,44 @@
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 anonymous user" do
88+
expect(Guardian.new.can_detect_language?(post)).to eq(false)
89+
end
90+
91+
it "returns false when the post user is not in restrict_translation_by_poster_group" do
92+
SiteSetting.restrict_translation_by_poster_group = "#{group.id+1}"
93+
94+
expect(guardian.can_detect_language?(post)).to eq(false)
95+
end
96+
97+
context "when post author is in allowed groups" do
98+
before do
99+
SiteSetting.restrict_translation_by_group = "#{group.id}"
100+
SiteSetting.restrict_translation_by_poster_group = "#{group.id}"
101+
end
102+
103+
it "returns true when the post is not a small action post" do
104+
expect(guardian.can_detect_language?(post)).to eq(true)
105+
end
106+
107+
it "returns false when the post is a small action post" do
108+
post.update(post_type: Post.types[:small_action])
109+
110+
expect(guardian.can_detect_language?(post)).to eq(false)
111+
end
112+
113+
it "returns false when the post raw is empty" do
114+
post.update(raw: "")
115+
116+
expect(guardian.can_detect_language?(post)).to eq(false)
117+
end
118+
end
119+
end
80120
end

spec/models/post_spec.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,40 @@
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+
context "when user and posts are in the right group" do
37+
before do
38+
SiteSetting.restrict_translation_by_group = "#{group.id}"
39+
SiteSetting.restrict_translation_by_poster_group = "#{group.id}"
40+
end
41+
42+
it "queues the post for language detection" do
43+
PostCreator.create!(user, raw: "it's a cat on a boat", topic_id: topic.id)
44+
expect(Discourse.redis.sismember(DiscourseTranslator::LANG_DETECT_NEEDED, post.id)).to be_truthy
45+
end
46+
47+
it "queues the post for language detection when edited" do
48+
post = PostCreator.create!(user, raw: "it's a cat on a boat", topic_id: topic.id)
49+
Discourse.redis.spop(DiscourseTranslator::LANG_DETECT_NEEDED)
50+
51+
PostRevisor.new(post).revise!(post.user, { raw: "it's a bat on a coat" })
52+
53+
expect(Discourse.redis.sismember(DiscourseTranslator::LANG_DETECT_NEEDED, post.id)).to be_truthy
54+
end
55+
end
56+
57+
context "when user and posts are not in the right group" do
58+
it "does not queue the post for language detection" do
59+
PostCreator.create!(user, raw: "it's a cat on a boat", topic_id: topic.id)
60+
61+
expect(Discourse.redis.sismember(DiscourseTranslator::LANG_DETECT_NEEDED, post.id)).to be_falsey
62+
end
63+
end
64+
end
3065
end
66+

spec/serializers/post_serializer_spec.rb

Lines changed: 28 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
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)
@@ -21,25 +21,15 @@
2121
describe "when translator enabled" do
2222
before do
2323
SiteSetting.translator_enabled = true
24-
Jobs.run_later!
2524
end
2625

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

31-
it "cannot translate" do
32-
expect(serializer.can_translate).to eq(false)
33-
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
29+
before do
30+
SiteSetting.restrict_translation_by_group = "#{Group::AUTO_GROUPS[:everyone]}"
31+
SiteSetting.restrict_translation_by_poster_group = ""
4132
end
42-
let(:serializer) { PostSerializer.new(empty_post, scope: Guardian.new) }
4333

4434
it "cannot translate" do
4535
expect(serializer.can_translate).to eq(false)
@@ -49,61 +39,46 @@
4939
describe "logged in user" do
5040
let(:serializer) { PostSerializer.new(post, scope: Guardian.new(user)) }
5141

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

56-
expect(serializer.can_translate).to eq(false)
57-
end
45+
expect(serializer.can_translate).to eq(false)
5846
end
5947

60-
describe "when post is not in restrict_translation_by_poster_group" do
61-
it "cannot translate" do
48+
describe "user is in restrict_translation_by_group" do
49+
before do
6250
SiteSetting.restrict_translation_by_group = "#{group.id}"
63-
SiteSetting.restrict_translation_by_poster_group = ""
64-
65-
expect(serializer.can_translate).to eq(false)
6651
end
67-
end
6852

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}"
53+
it "cannot translate when post author is not in restrict_translation_by_poster_group" do
54+
SiteSetting.restrict_translation_by_poster_group = "#{group.id}"
55+
56+
expect(serializer.can_translate).to eq(false)
7357
end
7458

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)
59+
describe "post author in restrict_translation_by_poster_group and locale is :xx" do
60+
before do
61+
SiteSetting.restrict_translation_by_poster_group = "#{post_user_group.id}"
62+
I18n.stubs(:locale).returns(:pt)
7863
end
7964

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)
65+
it "cannot translate when post does not have DETECTED_LANG_CUSTOM_FIELD" do
66+
expect(serializer.can_translate).to eq(false)
8767
end
88-
end
8968

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"
69+
it "cannot translate when post has DETECTED_LANG_CUSTOM_FIELD matches locale" do
70+
post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] = "pt"
9471
post.save
95-
end
9672

97-
it { expect(serializer.can_translate).to eq(false) }
98-
end
73+
expect(serializer.can_translate).to eq(false)
74+
end
9975

100-
describe "when post has DETECTED_LANG_CUSTOM_FIELD does not match user locale" do
101-
before do
76+
it "can translate when post has DETECTED_LANG_CUSTOM_FIELD does not match locale" do
10277
post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] = "jp"
10378
post.save
104-
end
10579

106-
it { expect(serializer.can_translate).to eq(true) }
80+
expect(serializer.can_translate).to eq(true)
81+
end
10782
end
10883
end
10984
end

0 commit comments

Comments
 (0)