diff --git a/service/lib/agama/dbus/software/manager.rb b/service/lib/agama/dbus/software/manager.rb index 552a46aa47..25987eea04 100644 --- a/service/lib/agama/dbus/software/manager.rb +++ b/service/lib/agama/dbus/software/manager.rb @@ -123,7 +123,7 @@ def initialize(backend, logger) def available_base_products backend.products.map do |id, data| - [id, data["name"], { "description" => data["description"] }].freeze + [id, data["name"], { "description" => localized_description(data) }].freeze end end @@ -181,6 +181,31 @@ def register_callbacks end end + # find translated product description if available + # @param data [Hash] product configuration from the YAML file + # @return [String,nil] Translated product description (if available) + # or the untranslated description, nil if not found + def localized_description(data) + translations = data["translations"]&.[]("description") + lang = ENV["LANG"] || "" + + # no translations or language not set, return untranslated value + return data["description"] if !translations.is_a?(Hash) || lang.empty? + + # remove the character encoding if present + lang = lang.split(".").first + # full matching (language + country) + return translations[lang] if translations[lang] + + # remove the country part + lang = lang.split("_").first + # partial match (just the language) + return translations[lang] if translations[lang] + + # fallback to original untranslated description + data["description"] + end + USER_SELECTED_PATTERN = 0 AUTO_SELECTED_PATTERN = 1 def compute_patterns diff --git a/service/lib/agama/ui_locale.rb b/service/lib/agama/ui_locale.rb index cc67ba9475..01c1b10564 100644 --- a/service/lib/agama/ui_locale.rb +++ b/service/lib/agama/ui_locale.rb @@ -47,7 +47,7 @@ def initialize(locale_client, &block) def change_locale(locale) # TODO: check if we can use UTF-8 everywhere including strange arch consoles Yast::WFM.SetLanguage(locale, "UTF-8") - # explicitelly set ENV to get localization also from libraries like libstorage + # explicitly set ENV to get localization also from libraries like libstorage ENV["LANG"] = locale + ".UTF-8" log.info "set yast language to #{locale}" # explicit call to textdomain to force fast gettext change of language ASAP diff --git a/service/test/agama/dbus/software/manager_test.rb b/service/test/agama/dbus/software/manager_test.rb index f6eda1223b..b75490ab43 100644 --- a/service/test/agama/dbus/software/manager_test.rb +++ b/service/test/agama/dbus/software/manager_test.rb @@ -140,4 +140,68 @@ expect(installed).to eq(true) end end + + describe "#available_base_products" do + # testing product with translations + products = { + "Tumbleweed" => { + "name" => "openSUSE Tumbleweed", + "description" => "Original description", + "translations" => { + "description" => { + "cs" => "Czech translation", + "es" => "Spanish translation" + } + } + } + } + + it "returns product ID and name" do + expect(backend).to receive(:products).and_return(products) + + product = subject.available_base_products.first + expect(product[0]).to eq("Tumbleweed") + expect(product[1]).to eq("openSUSE Tumbleweed") + end + + it "returns untranslated description when the language is not set" do + allow(ENV).to receive(:[]).with("LANG").and_return(nil) + expect(backend).to receive(:products).and_return(products) + + product = subject.available_base_products.first + expect(product[2]["description"]).to eq("Original description") + end + + it "returns Czech translation if locale is \"cs_CZ.UTF-8\"" do + allow(ENV).to receive(:[]).with("LANG").and_return("cs_CZ.UTF-8") + expect(backend).to receive(:products).and_return(products) + + product = subject.available_base_products.first + expect(product[2]["description"]).to eq("Czech translation") + end + + it "returns Czech translation if locale is \"cs\"" do + allow(ENV).to receive(:[]).with("LANG").and_return("cs") + expect(backend).to receive(:products).and_return(products) + + product = subject.available_base_products.first + expect(product[2]["description"]).to eq("Czech translation") + end + + it "return untranslated description when translation is not available" do + allow(ENV).to receive(:[]).with("LANG").and_return("cs_CZ.UTF-8") + + # testing product without translations + untranslated = { + "Tumbleweed" => { + "name" => "openSUSE Tumbleweed", + "description" => "Original description" + } + } + expect(backend).to receive(:products).and_return(untranslated) + + product = subject.available_base_products.first + expect(product[2]["description"]).to eq("Original description") + end + end end