Skip to content

Commit

Permalink
[service] Adapt product translations to changes in registration
Browse files Browse the repository at this point in the history
  • Loading branch information
joseivanlopez committed Nov 15, 2023
1 parent 03e29fa commit 6709506
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 107 deletions.
25 changes: 0 additions & 25 deletions service/lib/agama/dbus/software/manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,31 +149,6 @@ def register_callbacks
backend.on_issues_change { issues_properties_changed }
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
Expand Down
2 changes: 1 addition & 1 deletion service/lib/agama/dbus/software/product.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def issues

def available_products
backend.products.map do |product|
[product.id, product.display_name, { "description" => product.description }]
[product.id, product.display_name, { "description" => product.localized_description }]
end
end

Expand Down
49 changes: 45 additions & 4 deletions service/lib/agama/software/product.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,22 @@ class Product

# Name of the product to be display.
#
# @return [String]
# @return [String, nil]
attr_accessor :display_name

# Description of the product.
#
# @return [String]
# @return [String, nil]
attr_accessor :description

# Internal name of the product. This is relevant for registering the product.
#
# @return [String]
# @return [String, nil]
attr_accessor :name

# Version of the product. This is relevant for registering the product.
#
# @return [String] E.g., "1.0".
# @return [String, nil] E.g., "1.0".
attr_accessor :version

# List of repositories.
Expand Down Expand Up @@ -73,6 +73,19 @@ class Product
# @return [Array<String>]
attr_accessor :optional_patterns

# Product translations.
#
# @example
# product.translations #=>
# {
# "description" => {
# "cs" => "Czech translation",
# "es" => "Spanish translation"
# }
#
# @return [Hash<String, Hash<String, String>>]
attr_accessor :translations

# @param id [string] Product id.
def initialize(id)
@id = id
Expand All @@ -81,6 +94,34 @@ def initialize(id)
@optional_packages = []
@mandatory_patterns = []
@optional_patterns = []
@translations = {}
end

# Localized product description.
#
# If there is no translation for the current language, then the untranslated description is
# used.
#
# @return [String, nil]
def localized_description
translations = self.translations["description"]
lang = ENV["LANG"]

# No translations or language not set, return untranslated value.
return description unless translations && lang

# 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.
description
end
end
end
Expand Down
1 change: 1 addition & 0 deletions service/lib/agama/software/product_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def build
product.optional_packages = data[:optional_packages]
product.mandatory_patterns = data[:mandatory_patterns]
product.optional_patterns = data[:optional_patterns]
product.translations = attrs["translations"] || {}
end
end
end
Expand Down
64 changes: 0 additions & 64 deletions service/test/agama/dbus/software/manager_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,68 +135,4 @@
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
40 changes: 27 additions & 13 deletions service/test/agama/software/product_builder_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

# Copyright (c) [2022-2023] SUSE LLC
# Copyright (c) [2023] SUSE LLC
#
# All Rights Reserved.
#
Expand Down Expand Up @@ -38,10 +38,16 @@
let(:products) do
[
{
"id" => "Test1",
"name" => "Product Test 1",
"description" => "This is a test product named Test 1",
"software" => {
"id" => "Test1",
"name" => "Product Test 1",
"description" => "This is a test product named Test 1",
"translations" => {
"description" => {
"cs" => "Czech",
"es" => "Spanish"
}
},
"software" => {
"installation_repositories" => [
{
"url" => "https://repos/test1/x86_64/product/",
Expand Down Expand Up @@ -141,7 +147,8 @@
mandatory_patterns: ["pattern1-1", "pattern1-2"],
optional_patterns: ["pattern1-3"],
mandatory_packages: ["package1-1", "package1-2", "package1-3"],
optional_packages: ["package1-5"]
optional_packages: ["package1-5"],
translations: { "description" => { "cs" => "Czech", "es" => "Spanish" } }
),
an_object_having_attributes(
id: "Test2",
Expand All @@ -153,7 +160,8 @@
mandatory_patterns: ["pattern2-1"],
optional_patterns: [],
mandatory_packages: [],
optional_packages: []
optional_packages: [],
translations: {}
)
)
end
Expand Down Expand Up @@ -183,7 +191,8 @@
mandatory_patterns: ["pattern1-1", "pattern1-2"],
optional_patterns: ["pattern1-4"],
mandatory_packages: ["package1-1", "package1-2", "package1-3"],
optional_packages: ["package1-5"]
optional_packages: ["package1-5"],
translations: { "description" => { "cs" => "Czech", "es" => "Spanish" } }
),
an_object_having_attributes(
id: "Test2",
Expand All @@ -195,7 +204,8 @@
mandatory_patterns: ["pattern2-1"],
optional_patterns: [],
mandatory_packages: [],
optional_packages: []
optional_packages: [],
translations: {}
),
an_object_having_attributes(
id: "Test3",
Expand All @@ -207,7 +217,8 @@
mandatory_patterns: [],
optional_patterns: ["pattern3-1"],
mandatory_packages: [],
optional_packages: []
optional_packages: [],
translations: {}
)
)
end
Expand Down Expand Up @@ -237,7 +248,8 @@
mandatory_patterns: ["pattern1-1", "pattern1-2"],
optional_patterns: [],
mandatory_packages: ["package1-1", "package1-2", "package1-4"],
optional_packages: ["package1-5"]
optional_packages: ["package1-5"],
translations: { "description" => { "cs" => "Czech", "es" => "Spanish" } }
),
an_object_having_attributes(
id: "Test3",
Expand All @@ -249,7 +261,8 @@
mandatory_patterns: [],
optional_patterns: [],
mandatory_packages: [],
optional_packages: []
optional_packages: [],
translations: {}
)
)
end
Expand Down Expand Up @@ -279,7 +292,8 @@
mandatory_patterns: ["pattern1-1", "pattern1-2"],
optional_patterns: [],
mandatory_packages: ["package1-1", "package1-2"],
optional_packages: ["package1-5"]
optional_packages: ["package1-5"],
translations: { "description" => { "cs" => "Czech", "es" => "Spanish" } }
)
)
end
Expand Down
64 changes: 64 additions & 0 deletions service/test/agama/software/product_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# frozen_string_literal: true

# Copyright (c) [2023] SUSE LLC
#
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, contact SUSE LLC.
#
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.

require_relative "../../test_helper"
require "agama/software/product"

describe Agama::Software::Product do
subject { described_class.new("Test") }

describe "#localized_description" do
before do
subject.description = "Original description"
subject.translations = {
"description" => {
"cs" => "Czech translation",
"es" => "Spanish translation"
}
}
end

it "returns untranslated description when the language is not set" do
allow(ENV).to receive(:[]).with("LANG").and_return(nil)

expect(subject.localized_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(subject.localized_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(subject.localized_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")
subject.translations = {}

expect(subject.localized_description).to eq("Original description")
end
end
end

0 comments on commit 6709506

Please sign in to comment.