Skip to content

Commit

Permalink
Fix machine translations at the API (#10292)
Browse files Browse the repository at this point in the history
* Fix machine translations at the API

* Fix specs broken due to the changes

Co-authored-by: Antti Hukkanen <antti.hukkanen@mainiotech.fi>
  • Loading branch information
alecslupu and ahukkanen committed Jan 30, 2023
1 parent 1ce9d02 commit c2f9d92
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 8 deletions.
9 changes: 9 additions & 0 deletions decidim-core/lib/decidim/api/types/localized_string_type.rb
Expand Up @@ -8,6 +8,15 @@ class LocalizedStringType < Decidim::Api::Types::BaseObject

field :locale, GraphQL::Types::String, "The standard locale of this translation.", null: false
field :text, GraphQL::Types::String, "The content of this translation.", null: true
field :machine_translated, GraphQL::Types::Boolean, "Whether this string is machine translated or not.", null: false

def machine_translated
if object.respond_to?(:machine_translated)
object.machine_translated.present?
else
false
end
end
end
end
end
25 changes: 20 additions & 5 deletions decidim-core/lib/decidim/api/types/translated_field_type.rb
Expand Up @@ -17,19 +17,34 @@ class TranslatedFieldType < Decidim::Api::Types::BaseObject
end

def locales
object.keys
(defined_translations.keys + machine_translations.keys).uniq
end

def translation(locale: "")
translations = object.stringify_keys
translations[locale]
display_translations[locale]
end

def translations(locales: [])
translations = object.stringify_keys
translations = display_translations
translations = translations.slice(*locales) unless locales.empty?

translations.map { |locale, text| OpenStruct.new(locale: locale, text: text) }
translations.map { |locale, text| OpenStruct.new(locale: locale, text: text, machine_translated: defined_translations[locale].blank?) }
end

private

def display_translations
@display_translations ||= locales.index_with do |locale|
defined_translations[locale].presence || machine_translations[locale]
end
end

def defined_translations
object.stringify_keys.except("machine_translations")
end

def machine_translations
object.stringify_keys["machine_translations"]&.stringify_keys || {}
end
end
end
Expand Down
48 changes: 48 additions & 0 deletions decidim-core/spec/types/localized_string_type_spec.rb
Expand Up @@ -27,6 +27,54 @@ module Core
expect(response).to include("text" => "A test locale.")
end
end

describe "machineTranslated" do
let(:query) { "{ machineTranslated }" }

it "returns false by default" do
expect(response).to include("machineTranslated" => false)
end

context "when the model responds to machine_translated" do
let(:model) { OpenStruct.new(machine_translated: true) }

it "returns the correct value" do
expect(response).to include("machineTranslated" => true)
end

context "and the model returns false" do
let(:model) { OpenStruct.new(machine_translated: false) }

it "returns the correct value" do
expect(response).to include("machineTranslated" => false)
end
end

context "and the model returns a nil" do
let(:model) { OpenStruct.new(machine_translated: nil) }

it "returns false" do
expect(response).to include("machineTranslated" => false)
end
end

context "and the model returns a non-boolean evaluating as present" do
let(:model) { OpenStruct.new(machine_translated: "true") }

it "returns true" do
expect(response).to include("machineTranslated" => true)
end
end

context "and the model returns a non-boolean evaluating as blank" do
let(:model) { OpenStruct.new(machine_translated: "") }

it "returns false" do
expect(response).to include("machineTranslated" => false)
end
end
end
end
end
end
end
56 changes: 56 additions & 0 deletions decidim-core/spec/types/translated_field_type_spec.rb
Expand Up @@ -8,6 +8,19 @@ module Core
describe TranslatedFieldType do
include_context "with a graphql class type"

shared_context "with machine translations" do
let(:model) do
{
ca: "Hola",
en: "Hello",
es: "",
machine_translations: {
es: "Ey"
}
}
end
end

let(:model) do
{
ca: "Hola",
Expand All @@ -21,6 +34,14 @@ module Core
it "returns the available locales" do
expect(response["locales"]).to include("en", "ca")
end

context "when there are machine translations" do
include_context "with machine translations"

it "returns all available locales with no duplicates" do
expect(response["locales"]).to include("en", "ca", "es")
end
end
end

describe "translations" do
Expand All @@ -33,6 +54,41 @@ module Core
expect(translations).to include("locale" => "ca", "text" => "Hola")
expect(translations).to include("locale" => "en", "text" => "Hello")
end

context "when there are machine translations" do
include_context "with machine translations"

let(:query) { "{ translations { locale text machineTranslated }}" }

it "returns correct translations" do
translations = response["translations"]
expect(translations.length).to eq(3)
expect(translations).to include("locale" => "ca", "text" => "Hola", "machineTranslated" => false)
expect(translations).to include("locale" => "en", "text" => "Hello", "machineTranslated" => false)
expect(translations).to include("locale" => "es", "text" => "Ey", "machineTranslated" => true)
end

context "with defined translation overriding machine translation" do
let(:model) do
{
ca: "Hola",
en: "Hello",
es: "Hola",
machine_translations: {
es: "Ey"
}
}
end

it "returns correct translations" do
translations = response["translations"]
expect(translations.length).to eq(3)
expect(translations).to include("locale" => "ca", "text" => "Hola", "machineTranslated" => false)
expect(translations).to include("locale" => "en", "text" => "Hello", "machineTranslated" => false)
expect(translations).to include("locale" => "es", "text" => "Hola", "machineTranslated" => false)
end
end
end
end

context "when locales are provided" do
Expand Down
Expand Up @@ -152,7 +152,10 @@
let!(:participatory_process_response) do
{
"announcement" => {
"locales" => participatory_process.announcement.keys.sort,
"locales" => (
participatory_process.announcement.keys.excluding("machine_translations") +
participatory_process.announcement["machine_translations"].keys
).sort,
"translation" => participatory_process.announcement[locale]
},
"attachments" => [],
Expand Down
Expand Up @@ -36,7 +36,8 @@ module ParticipatoryProcesses
let(:query) { '{ title { locales translation(locale:"en") } }' }

it "returns its title" do
expect(response["title"]["locales"]).to include(*model.title.keys)
expected_keys = (model.description.keys.excluding("machine_translations") + model.description["machine_translations"].keys).sort
expect(response["title"]["locales"]).to include(*expected_keys)
expect(response["title"]["translation"]).to eq(model.title["en"])
end
end
Expand All @@ -45,7 +46,8 @@ module ParticipatoryProcesses
let(:query) { '{ description { locales translation(locale:"en") } }' }

it "returns its description" do
expect(response["description"]["locales"]).to include(*model.description.keys)
expected_keys = (model.description.keys.excluding("machine_translations") + model.description["machine_translations"].keys).sort
expect(response["description"]["locales"]).to include(*expected_keys)
expect(response["description"]["translation"]).to eq(model.description["en"])
end
end
Expand Down

0 comments on commit c2f9d92

Please sign in to comment.