Skip to content

Commit 51cf6a2

Browse files
committed
update job
1 parent 051adea commit 51cf6a2

File tree

2 files changed

+58
-22
lines changed

2 files changed

+58
-22
lines changed

app/jobs/regular/translate_posts.rb

+17-14
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,24 @@ def execute(args)
1414
locales = SiteSetting.automatic_translation_target_languages.split("|")
1515
return if locales.blank?
1616

17-
# keeping this query simple by just getting any post with a missing localization
18-
posts =
19-
Post
20-
.left_joins(:post_localizations)
21-
.where(deleted_at: nil)
22-
.where("posts.user_id > 0")
23-
.where.not(raw: [nil, ""])
24-
.group("posts.id")
25-
.having(
26-
"COUNT(DISTINCT CASE WHEN post_localizations.locale IN (?) THEN post_localizations.locale END) < ?",
27-
locales,
28-
locales.size,
17+
sql = <<~SQL
18+
SELECT DISTINCT posts.*
19+
FROM posts
20+
CROSS JOIN unnest(ARRAY[#{locales.map { |l| ActiveRecord::Base.connection.quote(l) }.join(",")}]) AS target_locale(locale)
21+
WHERE
22+
posts.deleted_at IS NULL
23+
AND posts.user_id > 0
24+
AND posts.raw IS NOT NULL AND posts.raw <> ''
25+
AND posts.locale IS NOT NULL
26+
AND target_locale.locale != posts.locale
27+
AND NOT EXISTS (
28+
SELECT 1 FROM post_localizations
29+
WHERE post_localizations.post_id = posts.id
30+
AND post_localizations.locale = target_locale.locale
2931
)
30-
.order(updated_at: :desc)
31-
.limit(BATCH_SIZE)
32+
SQL
33+
34+
posts = Post.find_by_sql(sql)
3235

3336
return if posts.empty?
3437

spec/jobs/translate_posts_spec.rb

+41-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
fab!(:post)
55
subject(:job) { described_class.new }
66

7-
let(:locales) { %w[en ja] }
7+
let(:locales) { %w[en ja de] }
88

99
before do
1010
SiteSetting.translator_enabled = true
@@ -41,13 +41,6 @@
4141
job.execute({})
4242
end
4343

44-
it "translates posts to the configured locales" do
45-
DiscourseTranslator::PostTranslator.expects(:translate).with(post, "en").at_least_once
46-
DiscourseTranslator::PostTranslator.expects(:translate).with(post, "ja").at_least_once
47-
48-
job.execute({})
49-
end
50-
5144
it "skips posts that already have localizations" do
5245
Post.all.each do |post|
5346
Fabricate(:post_localization, post:, locale: "en")
@@ -67,19 +60,59 @@
6760
end
6861

6962
it "handles translation errors gracefully" do
63+
post.update(locale: "es")
7064
DiscourseTranslator::PostTranslator
7165
.expects(:translate)
7266
.with(post, "en")
7367
.raises(StandardError.new("API error"))
7468
DiscourseTranslator::PostTranslator.expects(:translate).with(post, "ja").once
69+
DiscourseTranslator::PostTranslator.expects(:translate).with(post, "de").once
7570

7671
expect { job.execute({}) }.not_to raise_error
7772
end
7873

7974
it "logs a summary after translation" do
75+
post.update(locale: "es")
8076
DiscourseTranslator::PostTranslator.stubs(:translate)
8177
DiscourseTranslator::VerboseLogger.expects(:log).with(includes("Translated 1 posts to en, ja"))
8278

8379
job.execute({})
8480
end
81+
82+
context "translation scenarios" do
83+
it "scenario 1: skips post when locale is not set" do
84+
DiscourseTranslator::PostTranslator.expects(:translate).never
85+
86+
job.execute({})
87+
end
88+
89+
it "scenario 2: returns post with locale 'es' if localizations for en/ja do not exist" do
90+
post = Fabricate(:post, locale: "es")
91+
92+
DiscourseTranslator::PostTranslator.expects(:translate).with(post, "en").once
93+
DiscourseTranslator::PostTranslator.expects(:translate).with(post, "ja").once
94+
DiscourseTranslator::PostTranslator.expects(:translate).with(post, "de").once
95+
96+
job.execute({})
97+
end
98+
99+
it "scenario 3: returns post with locale 'en' if ja localization does not exist" do
100+
post = Fabricate(:post, locale: "en")
101+
102+
DiscourseTranslator::PostTranslator.expects(:translate).with(post, "ja").once
103+
DiscourseTranslator::PostTranslator.expects(:translate).with(post, "de").once
104+
DiscourseTranslator::PostTranslator.expects(:translate).with(post, "en").never
105+
106+
job.execute({})
107+
end
108+
109+
it "scenario 4: skips post with locale 'en' if 'ja' localization already exists" do
110+
post = Fabricate(:post, locale: "en")
111+
Fabricate(:post_localization, post: post, locale: "ja")
112+
113+
DiscourseTranslator::PostTranslator.expects(:translate).never
114+
115+
job.execute({})
116+
end
117+
end
85118
end

0 commit comments

Comments
 (0)