mirror of
https://github.com/discourse/discourse-ai.git
synced 2025-11-13 12:49:01 +00:00
Related: https://github.com/discourse/discourse-translator/pull/310 This commit includes all the jobs and event hooks to localize posts, topics, and categories. A few notes: - `feature_name: "translation"` because the site setting is `ai-translation` and module is `Translation` - we will switch to proper ai-feature in the near future, and can consider using the persona_user as `localization.localizer_user_id` - keeping things flat within the module for now as we will be moving to ai-feature soon and have to rearrange - Settings renamed/introduced are: - ai_translation_backfill_rate (0) - ai_translation_backfill_limit_to_public_content (true) - ai_translation_backfill_max_age_days (5) - ai_translation_verbose_logs (false)
96 lines
3.1 KiB
Ruby
96 lines
3.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
describe DiscourseAi::Translation::CategoryLocalizer do
|
|
subject(:localizer) { described_class }
|
|
|
|
before do
|
|
Fabricate(:fake_model).tap do |fake_llm|
|
|
SiteSetting.public_send("ai_translation_model=", "custom:#{fake_llm.id}")
|
|
end
|
|
end
|
|
|
|
def post_raw_translator_stub(opts)
|
|
mock = instance_double(DiscourseAi::Translation::PostRawTranslator)
|
|
allow(DiscourseAi::Translation::PostRawTranslator).to receive(:new).with(
|
|
opts[:value],
|
|
opts[:locale],
|
|
).and_return(mock)
|
|
allow(mock).to receive(:translate).and_return(opts[:translated])
|
|
end
|
|
|
|
def short_text_translator_stub(opts)
|
|
mock = instance_double(DiscourseAi::Translation::ShortTextTranslator)
|
|
allow(DiscourseAi::Translation::ShortTextTranslator).to receive(:new).with(
|
|
opts[:value],
|
|
opts[:locale],
|
|
).and_return(mock)
|
|
allow(mock).to receive(:translate).and_return(opts[:translated])
|
|
end
|
|
|
|
fab!(:category) do
|
|
Fabricate(:category, name: "Test Category", description: "This is a test category")
|
|
end
|
|
|
|
describe ".localize" do
|
|
let(:target_locale) { :fr }
|
|
|
|
it "translates the category name and description" do
|
|
translated_cat_desc = "C'est une catégorie de test"
|
|
translated_cat_name = "Catégorie de Test"
|
|
short_text_translator_stub(
|
|
{ value: category.name, locale: target_locale, translated: translated_cat_name },
|
|
)
|
|
post_raw_translator_stub(
|
|
{ value: category.description, locale: target_locale, translated: translated_cat_desc },
|
|
)
|
|
|
|
res = localizer.localize(category, target_locale)
|
|
|
|
expect(res.name).to eq(translated_cat_name)
|
|
expect(res.description).to eq(translated_cat_desc)
|
|
end
|
|
|
|
it "handles locale format standardization" do
|
|
translated_cat_desc = "C'est une catégorie de test"
|
|
translated_cat_name = "Catégorie de Test"
|
|
short_text_translator_stub(
|
|
{ value: category.name, locale: :fr, translated: translated_cat_name },
|
|
)
|
|
post_raw_translator_stub(
|
|
{ value: category.description, locale: :fr, translated: translated_cat_desc },
|
|
)
|
|
|
|
res = localizer.localize(category, "fr")
|
|
|
|
expect(res.name).to eq(translated_cat_name)
|
|
expect(res.description).to eq(translated_cat_desc)
|
|
end
|
|
|
|
it "returns nil if category is blank" do
|
|
expect(localizer.localize(nil)).to be_nil
|
|
end
|
|
|
|
it "returns nil if target locale is blank" do
|
|
expect(localizer.localize(category, nil)).to be_nil
|
|
end
|
|
|
|
it "uses I18n.locale as default when no target locale is provided" do
|
|
I18n.locale = :es
|
|
translated_cat_desc = "C'est une catégorie de test"
|
|
translated_cat_name = "Esta es una categoría de prueba"
|
|
short_text_translator_stub(
|
|
{ value: category.name, locale: :es, translated: translated_cat_name },
|
|
)
|
|
post_raw_translator_stub(
|
|
{ value: category.description, locale: :es, translated: translated_cat_desc },
|
|
)
|
|
|
|
res = localizer.localize(category)
|
|
|
|
expect(res.name).to eq(translated_cat_name)
|
|
expect(res.description).to eq(translated_cat_desc)
|
|
expect(res.locale).to eq("es")
|
|
end
|
|
end
|
|
end
|