2022-01-01 13:38:12 +00:00
|
|
|
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
|
2021-06-01 12:20:20 +00:00
|
|
|
|
2016-12-06 10:46:26 +00:00
|
|
|
require 'rails_helper'
|
|
|
|
|
|
|
|
RSpec.describe Translation do
|
|
|
|
|
2018-10-18 12:16:29 +00:00
|
|
|
before(:all) do
|
2019-04-15 01:41:17 +00:00
|
|
|
described_class.where(locale: 'de-de').destroy_all
|
2021-11-15 15:58:19 +00:00
|
|
|
described_class.sync_locale_from_po('de-de')
|
2018-10-18 12:16:29 +00:00
|
|
|
end
|
2018-09-04 11:37:51 +00:00
|
|
|
|
2019-02-10 11:01:38 +00:00
|
|
|
context 'default string translations' do
|
2016-12-06 10:46:26 +00:00
|
|
|
|
|
|
|
it 'en with existing word' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.translate('en', 'New')).to eq('New')
|
2016-12-06 10:46:26 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'en-us with existing word' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.translate('en-us', 'New')).to eq('New')
|
2016-12-06 10:46:26 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'en with not existing word' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.translate('en', 'Some Not Existing Word')).to eq('Some Not Existing Word')
|
2016-12-06 10:46:26 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'de-de with existing word' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.translate('de-de', 'New')).to eq('Neu')
|
2016-12-06 10:46:26 +00:00
|
|
|
end
|
|
|
|
|
2019-04-15 01:41:17 +00:00
|
|
|
it 'de-de with not existing word' do
|
|
|
|
expect(described_class.translate('de-de', 'Some Not Existing Word')).to eq('Some Not Existing Word')
|
2016-12-06 10:46:26 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2021-11-15 15:58:19 +00:00
|
|
|
context 'when using find_source' do
|
|
|
|
it 'de-de with existing title case word' do
|
|
|
|
expect(described_class.find_source('de-de', 'New')).to have_attributes(source: 'New', target_initial: 'Neu', target: 'Neu')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'de-de with existing lower case word' do
|
|
|
|
expect(described_class.find_source('de-de', 'new')).to have_attributes(source: 'new', target_initial: 'neu', target: 'neu')
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'de-de with nonexisting existing source' do
|
|
|
|
expect(described_class.find_source('de-de', 'nonexisting-string')).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-02-10 11:01:38 +00:00
|
|
|
context 'default timestamp translations' do
|
|
|
|
|
|
|
|
it 'de-de with array' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.timestamp('de-de', 'Europe/Berlin', ['some value'])).to eq('["some value"]')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'not_existing with timestamp as string' do
|
2020-01-27 09:28:17 +00:00
|
|
|
expect(described_class.timestamp('not_existing', 'Europe/Berlin', '2018-10-10T10:00:00Z0')).to eq('2018-10-10 12:00:00 +0200')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'not_existing with time object' do
|
2020-01-27 09:28:17 +00:00
|
|
|
expect(described_class.timestamp('not_existing', 'Europe/Berlin', Time.zone.parse('2018-10-10T10:00:00Z0'))).to eq('2018-10-10 12:00:00 +0200')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'not_existing with invalid timestamp string' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.timestamp('not_existing', 'Europe/Berlin', 'something')).to eq('something')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'en-us with invalid time zone' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.timestamp('en-us', 'Invalid/TimeZone', '2018-10-10T10:00:00Z0')).to eq(Time.zone.parse('2018-10-10T10:00:00Z0').to_s)
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'en-us with timestamp as string' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.timestamp('en-us', 'Europe/Berlin', '2018-10-10T10:00:00Z0')).to eq('10/10/2018 12:00 (Europe/Berlin)')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'en-us with time object' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.timestamp('en-us', 'Europe/Berlin', Time.zone.parse('2018-10-10T10:00:00Z0'))).to eq('10/10/2018 12:00 (Europe/Berlin)')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'de-de with timestamp as string' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.timestamp('de-de', 'Europe/Berlin', '2018-10-10T10:00:00Z0')).to eq('10.10.2018 12:00 (Europe/Berlin)')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'de-de with time object' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.timestamp('de-de', 'Europe/Berlin', Time.zone.parse('2018-10-10T10:00:00Z0'))).to eq('10.10.2018 12:00 (Europe/Berlin)')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'default date translations' do
|
|
|
|
|
|
|
|
it 'de-de with array' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.date('de-de', ['some value'])).to eq('["some value"]')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'not_existing with date as string' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.date('not_existing', '2018-10-10')).to eq('2018-10-10')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'not_existing with date object' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.date('not_existing', Date.parse('2018-10-10'))).to eq('2018-10-10')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'not_existing with invalid data as string' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.date('not_existing', 'something')).to eq('something')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'en-us with date as string' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.date('en-us', '2018-10-10')).to eq('10/10/2018')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'en-us with date object' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.date('en-us', Date.parse('2018-10-10'))).to eq('10/10/2018')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'de-de with date as string' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.date('de-de', '2018-10-10')).to eq('10.10.2018')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'de-de with date object' do
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(described_class.date('de-de', Date.parse('2018-10-10'))).to eq('10.10.2018')
|
2019-02-10 11:01:38 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2018-09-04 11:37:51 +00:00
|
|
|
context 'remote_translation_need_update? tests' do
|
|
|
|
|
|
|
|
it 'translation is still the same' do
|
2021-11-15 15:58:19 +00:00
|
|
|
translation = described_class.where(locale: 'de-de').last
|
|
|
|
translations = described_class.where(locale: 'de-de').pluck(:id, :locale, :source, :target, :target_initial).to_a
|
2018-09-04 11:37:51 +00:00
|
|
|
expect(
|
2019-04-15 01:41:17 +00:00
|
|
|
described_class.remote_translation_need_update?(
|
2018-09-04 11:37:51 +00:00
|
|
|
{
|
2018-12-19 17:31:51 +00:00
|
|
|
'source' => translation.source,
|
|
|
|
'locale' => translation.locale,
|
|
|
|
'target' => translation.target,
|
2018-09-04 11:37:51 +00:00
|
|
|
'target_initial' => translation.target_initial,
|
|
|
|
}, translations
|
|
|
|
)
|
|
|
|
).to be false
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'translation target has locally changed' do
|
2021-11-15 15:58:19 +00:00
|
|
|
translation = described_class.where(locale: 'de-de').last
|
2018-09-04 11:37:51 +00:00
|
|
|
translation.target = 'some new translation'
|
|
|
|
translation.save!
|
2021-11-15 15:58:19 +00:00
|
|
|
translations = described_class.where(locale: 'de-de').pluck(:id, :locale, :source, :target, :target_initial).to_a
|
2018-09-04 11:37:51 +00:00
|
|
|
expect(
|
2019-04-15 01:41:17 +00:00
|
|
|
described_class.remote_translation_need_update?(
|
2018-09-04 11:37:51 +00:00
|
|
|
{
|
2018-12-19 17:31:51 +00:00
|
|
|
'source' => translation.source,
|
|
|
|
'locale' => translation.locale,
|
|
|
|
'target' => translation.target,
|
2018-09-04 11:37:51 +00:00
|
|
|
'target_initial' => translation.target_initial,
|
|
|
|
}, translations
|
|
|
|
)
|
|
|
|
).to be false
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'translation target has remotely changed' do
|
2021-11-15 15:58:19 +00:00
|
|
|
translation = described_class.where(locale: 'de-de').last
|
|
|
|
translations = described_class.where(locale: 'de-de').pluck(:id, :locale, :source, :target, :target_initial).to_a
|
2019-04-15 01:41:17 +00:00
|
|
|
(result, translation_result) = described_class.remote_translation_need_update?(
|
2018-09-04 11:37:51 +00:00
|
|
|
{
|
2018-12-19 17:31:51 +00:00
|
|
|
'source' => translation.source,
|
|
|
|
'locale' => translation.locale,
|
|
|
|
'target' => 'some new translation by remote',
|
2018-09-04 11:37:51 +00:00
|
|
|
'target_initial' => 'some new translation by remote',
|
|
|
|
}, translations
|
|
|
|
)
|
|
|
|
expect(result).to be true
|
|
|
|
expect(translation_result.attributes).to eq translation.attributes
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'translation target has remotely and locally changed' do
|
2021-11-15 15:58:19 +00:00
|
|
|
translation = described_class.where(locale: 'de-de').last
|
2018-09-04 11:37:51 +00:00
|
|
|
translation.target = 'some new translation'
|
|
|
|
translation.save!
|
2021-11-15 15:58:19 +00:00
|
|
|
translations = described_class.where(locale: 'de-de').pluck(:id, :locale, :source, :target, :target_initial).to_a
|
2018-09-04 11:37:51 +00:00
|
|
|
expect(
|
2019-04-15 01:41:17 +00:00
|
|
|
described_class.remote_translation_need_update?(
|
2018-09-04 11:37:51 +00:00
|
|
|
{
|
2018-12-19 17:31:51 +00:00
|
|
|
'source' => translation.source,
|
|
|
|
'locale' => translation.locale,
|
|
|
|
'target' => 'some new translation by remote',
|
2018-09-04 11:37:51 +00:00
|
|
|
'target_initial' => 'some new translation by remote',
|
|
|
|
}, translations
|
|
|
|
)
|
|
|
|
).to be false
|
|
|
|
end
|
2016-12-06 10:46:26 +00:00
|
|
|
|
2018-09-04 11:37:51 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'custom translation tests' do
|
2016-12-06 10:46:26 +00:00
|
|
|
|
|
|
|
it 'cycle of change and reload translation' do
|
2018-09-04 11:37:51 +00:00
|
|
|
locale = 'de-de'
|
2016-12-06 10:46:26 +00:00
|
|
|
|
|
|
|
# check for non existing custom changes
|
2019-04-15 01:41:17 +00:00
|
|
|
list = described_class.lang(locale)
|
2017-10-01 12:25:52 +00:00
|
|
|
list['list'].each do |item|
|
2021-11-15 15:58:19 +00:00
|
|
|
translation = described_class.find_source(locale, item[1])
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(translation.class).to be(described_class)
|
2016-12-06 10:46:26 +00:00
|
|
|
expect(locale).to eq(translation.locale)
|
|
|
|
expect(translation.target).to eq(translation.target_initial)
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2016-12-06 10:46:26 +00:00
|
|
|
|
|
|
|
# add custom changes
|
2021-11-15 15:58:19 +00:00
|
|
|
translation = described_class.find_source(locale, 'open')
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(translation.class).to be(described_class)
|
2016-12-06 10:46:26 +00:00
|
|
|
expect(translation.target).to eq('offen')
|
|
|
|
expect(translation.target_initial).to eq('offen')
|
|
|
|
translation.target = 'offen2'
|
|
|
|
translation.save!
|
|
|
|
|
2019-04-15 01:41:17 +00:00
|
|
|
list = described_class.lang(locale)
|
2017-10-01 12:25:52 +00:00
|
|
|
list['list'].each do |item|
|
2021-11-15 15:58:19 +00:00
|
|
|
translation = described_class.find_source(locale, item[1])
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(translation.class).to be(described_class)
|
2016-12-06 10:46:26 +00:00
|
|
|
expect(locale).to eq(translation.locale)
|
|
|
|
if translation.source == 'open'
|
|
|
|
expect(translation.target).to eq('offen2')
|
|
|
|
expect(translation.target_initial).to eq('offen')
|
|
|
|
else
|
|
|
|
expect(translation.target).to eq(translation.target_initial)
|
|
|
|
end
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2016-12-06 10:46:26 +00:00
|
|
|
|
|
|
|
# check for existing custom changes after new translations are loaded
|
2021-11-15 15:58:19 +00:00
|
|
|
described_class.sync_locale_from_po(locale)
|
2019-04-15 01:41:17 +00:00
|
|
|
list = described_class.lang(locale)
|
2017-10-01 12:25:52 +00:00
|
|
|
list['list'].each do |item|
|
2021-11-15 15:58:19 +00:00
|
|
|
translation = described_class.find_source(locale, item[1])
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(translation.class).to be(described_class)
|
2016-12-06 10:46:26 +00:00
|
|
|
expect(locale).to eq(translation.locale)
|
|
|
|
if translation.source == 'open'
|
|
|
|
expect(translation.target).to eq('offen2')
|
|
|
|
expect(translation.target_initial).to eq('offen')
|
|
|
|
else
|
|
|
|
expect(translation.target).to eq(translation.target_initial)
|
|
|
|
end
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2016-12-06 10:46:26 +00:00
|
|
|
|
|
|
|
# reset custom translations and check for non existing custom changes
|
2019-04-15 01:41:17 +00:00
|
|
|
described_class.reset(locale)
|
|
|
|
list = described_class.lang(locale)
|
2017-10-01 12:25:52 +00:00
|
|
|
list['list'].each do |item|
|
2021-11-15 15:58:19 +00:00
|
|
|
translation = described_class.find_source(locale, item[1])
|
2019-04-15 01:41:17 +00:00
|
|
|
expect(translation.class).to be(described_class)
|
2016-12-06 10:46:26 +00:00
|
|
|
expect(locale).to eq(translation.locale)
|
|
|
|
expect(translation.target).to eq(translation.target_initial)
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2016-12-06 10:46:26 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|