translation_spec.rb 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe Translation do
  4. before(:all) do
  5. described_class.where(locale: 'de-de').destroy_all
  6. described_class.sync_locale_from_po('de-de')
  7. end
  8. context 'default string translations' do
  9. it 'en with existing word' do
  10. expect(described_class.translate('en', 'New')).to eq('New')
  11. end
  12. it 'en-us with existing word' do
  13. expect(described_class.translate('en-us', 'New')).to eq('New')
  14. end
  15. it 'en with not existing word' do
  16. expect(described_class.translate('en', 'Some Not Existing Word')).to eq('Some Not Existing Word')
  17. end
  18. it 'de-de with existing word' do
  19. expect(described_class.translate('de-de', 'New')).to eq('Neu')
  20. end
  21. it 'de-de with not existing word' do
  22. expect(described_class.translate('de-de', 'Some Not Existing Word')).to eq('Some Not Existing Word')
  23. end
  24. it 'format string with given arguments' do
  25. expect(described_class.translate('en', 'a %s string', 'given')).to eq('a given string')
  26. end
  27. end
  28. context 'when using find_source' do
  29. it 'de-de with existing title case word' do
  30. expect(described_class.find_source('de-de', 'New')).to have_attributes(source: 'New', target_initial: 'Neu', target: 'Neu')
  31. end
  32. it 'de-de with existing lower case word' do
  33. expect(described_class.find_source('de-de', 'new')).to have_attributes(source: 'new', target_initial: 'neu', target: 'neu')
  34. end
  35. it 'de-de with nonexisting existing source' do
  36. expect(described_class.find_source('de-de', 'nonexisting-string')).to be_nil
  37. end
  38. end
  39. context 'default timestamp translations' do
  40. it 'de-de with array' do
  41. expect(described_class.timestamp('de-de', 'Europe/Berlin', ['some value'])).to eq('["some value"]')
  42. end
  43. it 'not_existing with timestamp as string' do
  44. expect(described_class.timestamp('not_existing', 'Europe/Berlin', '2018-10-10T10:00:00Z0')).to eq('2018-10-10 12:00:00 +0200')
  45. end
  46. it 'not_existing with time object' do
  47. 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')
  48. end
  49. it 'not_existing with invalid timestamp string' do
  50. expect(described_class.timestamp('not_existing', 'Europe/Berlin', 'something')).to eq('something')
  51. end
  52. it 'en-us with invalid time zone' do
  53. 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)
  54. end
  55. it 'en-us with timestamp as string (am)' do
  56. expect(described_class.timestamp('en-us', 'Europe/Berlin', '2018-10-10T01:00:00Z0')).to eq('10/10/2018 3:00 am (Europe/Berlin)')
  57. end
  58. it 'en-us with timestamp as string (pm)' do
  59. expect(described_class.timestamp('en-us', 'Europe/Berlin', '2018-10-10T10:00:00Z0')).to eq('10/10/2018 12:00 pm (Europe/Berlin)')
  60. end
  61. it 'en-us with time object (am)' do
  62. expect(described_class.timestamp('en-us', 'Europe/Berlin', Time.zone.parse('2018-10-10T01:00:00Z0'))).to eq('10/10/2018 3:00 am (Europe/Berlin)')
  63. end
  64. it 'en-us with time object (pm)' do
  65. expect(described_class.timestamp('en-us', 'Europe/Berlin', Time.zone.parse('2018-10-10T10:00:00Z0'))).to eq('10/10/2018 12:00 pm (Europe/Berlin)')
  66. end
  67. it 'de-de with timestamp as string' do
  68. expect(described_class.timestamp('de-de', 'Europe/Berlin', '2018-10-10T10:00:00Z0')).to eq('10.10.2018 12:00 (Europe/Berlin)')
  69. end
  70. it 'de-de with time object' do
  71. 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)')
  72. end
  73. end
  74. context 'default date translations' do
  75. it 'de-de with array' do
  76. expect(described_class.date('de-de', ['some value'])).to eq('["some value"]')
  77. end
  78. it 'not_existing with date as string' do
  79. expect(described_class.date('not_existing', '2018-10-10')).to eq('2018-10-10')
  80. end
  81. it 'not_existing with date object' do
  82. expect(described_class.date('not_existing', Date.parse('2018-10-10'))).to eq('2018-10-10')
  83. end
  84. it 'not_existing with invalid data as string' do
  85. expect(described_class.date('not_existing', 'something')).to eq('something')
  86. end
  87. it 'en-us with date as string' do
  88. expect(described_class.date('en-us', '2018-10-10')).to eq('10/10/2018')
  89. end
  90. it 'en-us with date object' do
  91. expect(described_class.date('en-us', Date.parse('2018-10-10'))).to eq('10/10/2018')
  92. end
  93. it 'de-de with date as string' do
  94. expect(described_class.date('de-de', '2018-10-10')).to eq('10.10.2018')
  95. end
  96. it 'de-de with date object' do
  97. expect(described_class.date('de-de', Date.parse('2018-10-10'))).to eq('10.10.2018')
  98. end
  99. end
  100. context 'remote_translation_need_update? tests' do
  101. it 'translation is still the same' do
  102. translation = described_class.where(locale: 'de-de').last
  103. translations = described_class.where(locale: 'de-de').pluck(:id, :locale, :source, :target, :target_initial).to_a
  104. expect(
  105. described_class.remote_translation_need_update?(
  106. {
  107. 'source' => translation.source,
  108. 'locale' => translation.locale,
  109. 'target' => translation.target,
  110. 'target_initial' => translation.target_initial,
  111. }, translations
  112. )
  113. ).to be false
  114. end
  115. it 'translation target has locally changed' do
  116. translation = described_class.where(locale: 'de-de').last
  117. translation.target = 'some new translation'
  118. translation.save!
  119. translations = described_class.where(locale: 'de-de').pluck(:id, :locale, :source, :target, :target_initial).to_a
  120. expect(
  121. described_class.remote_translation_need_update?(
  122. {
  123. 'source' => translation.source,
  124. 'locale' => translation.locale,
  125. 'target' => translation.target,
  126. 'target_initial' => translation.target_initial,
  127. }, translations
  128. )
  129. ).to be false
  130. end
  131. it 'translation target has remotely changed' do
  132. translation = described_class.where(locale: 'de-de').last
  133. translations = described_class.where(locale: 'de-de').pluck(:id, :locale, :source, :target, :target_initial).to_a
  134. (result, translation_result) = described_class.remote_translation_need_update?(
  135. {
  136. 'source' => translation.source,
  137. 'locale' => translation.locale,
  138. 'target' => 'some new translation by remote',
  139. 'target_initial' => 'some new translation by remote',
  140. }, translations
  141. )
  142. expect(result).to be true
  143. expect(translation_result.attributes).to eq translation.attributes
  144. end
  145. it 'translation target has remotely and locally changed' do
  146. translation = described_class.where(locale: 'de-de').last
  147. translation.target = 'some new translation'
  148. translation.save!
  149. translations = described_class.where(locale: 'de-de').pluck(:id, :locale, :source, :target, :target_initial).to_a
  150. expect(
  151. described_class.remote_translation_need_update?(
  152. {
  153. 'source' => translation.source,
  154. 'locale' => translation.locale,
  155. 'target' => 'some new translation by remote',
  156. 'target_initial' => 'some new translation by remote',
  157. }, translations
  158. )
  159. ).to be false
  160. end
  161. end
  162. context 'custom translation tests' do
  163. it 'cycle of change and reload translation' do
  164. locale = 'de-de'
  165. # check for non existing custom changes
  166. list = described_class.lang(locale)
  167. list['list'].each do |item|
  168. translation = described_class.find_source(locale, item[1])
  169. expect(translation.class).to be(described_class)
  170. expect(locale).to eq(translation.locale)
  171. expect(translation.target).to eq(translation.target_initial)
  172. end
  173. # add custom changes
  174. translation = described_class.find_source(locale, 'open')
  175. expect(translation.class).to be(described_class)
  176. expect(translation.target).to eq('offen')
  177. expect(translation.target_initial).to eq('offen')
  178. translation.target = 'offen2'
  179. translation.save!
  180. list = described_class.lang(locale)
  181. list['list'].each do |item|
  182. translation = described_class.find_source(locale, item[1])
  183. expect(translation.class).to be(described_class)
  184. expect(locale).to eq(translation.locale)
  185. if translation.source == 'open'
  186. expect(translation.target).to eq('offen2')
  187. expect(translation.target_initial).to eq('offen')
  188. else
  189. expect(translation.target).to eq(translation.target_initial)
  190. end
  191. end
  192. # check for existing custom changes after new translations are loaded
  193. described_class.sync_locale_from_po(locale)
  194. list = described_class.lang(locale)
  195. list['list'].each do |item|
  196. translation = described_class.find_source(locale, item[1])
  197. expect(translation.class).to be(described_class)
  198. expect(locale).to eq(translation.locale)
  199. if translation.source == 'open'
  200. expect(translation.target).to eq('offen2')
  201. expect(translation.target_initial).to eq('offen')
  202. else
  203. expect(translation.target).to eq(translation.target_initial)
  204. end
  205. end
  206. # reset custom translations and check for non existing custom changes
  207. described_class.reset(locale)
  208. list = described_class.lang(locale)
  209. list['list'].each do |item|
  210. translation = described_class.find_source(locale, item[1])
  211. expect(translation.class).to be(described_class)
  212. expect(locale).to eq(translation.locale)
  213. expect(translation.target).to eq(translation.target_initial)
  214. end
  215. end
  216. end
  217. end