1 require File.join( File.dirname(__FILE__), '..', '..', 'test_helper' )
2 require 'active_record'
3 require 'globalize/model/active_record'
5 # Hook up model translation
6 ActiveRecord::Base.send(:include, Globalize::Model::ActiveRecord::Translated)
9 require File.join( File.dirname(__FILE__), '..', '..', 'data', 'post' )
11 class TranslatedTest < ActiveSupport::TestCase
13 I18n.locale = :'en-US'
15 reset_db! File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'data', 'schema.rb'))
16 ActiveRecord::Base.locale = nil
23 test "modifiying translated fields" do
24 post = Post.create :subject => 'foo'
25 assert_equal 'foo', post.subject
27 assert_equal 'bar', post.subject
30 test "modifiying translated fields while switching locales" do
31 post = Post.create :subject => 'foo'
32 assert_equal 'foo', post.subject
33 I18n.locale = :'de-DE'
35 assert_equal 'bar', post.subject
36 I18n.locale = :'en-US'
37 assert_equal 'foo', post.subject
38 I18n.locale = :'de-DE'
42 test "has post_translations" do
44 assert_nothing_raised { post.globalize_translations }
47 test "has German post_translations" do
49 post = Post.create :subject => 'foo'
50 assert_equal 1, post.globalize_translations.size
52 assert_equal 1, post.globalize_translations.size
55 test "returns the value passed to :subject" do
57 assert_equal 'foo', (post.subject = 'foo')
60 test "translates subject and content into en-US" do
61 post = Post.create :subject => 'foo', :content => 'bar'
62 assert_equal 'foo', post.subject
63 assert_equal 'bar', post.content
66 assert_equal 'foo', post.subject
67 assert_equal 'bar', post.content
70 test "finds a German post" do
71 post = Post.create :subject => 'foo (en)', :content => 'bar'
74 post.subject = 'baz (de)'
76 assert_equal 'baz (de)', Post.first.subject
77 I18n.locale = :'en-US'
78 assert_equal 'foo (en)', Post.first.subject
81 test "saves an English post and loads test correctly" do
83 post = Post.create :subject => 'foo', :content => 'bar'
86 assert_equal 'foo', post.subject
87 assert_equal 'bar', post.content
90 test "updates an attribute" do
91 post = Post.create :subject => 'foo', :content => 'bar'
92 post.update_attribute :subject, 'baz'
93 assert_equal 'baz', Post.first.subject
96 test "update_attributes failure" do
97 post = Post.create :subject => 'foo', :content => 'bar'
98 assert !post.update_attributes( { :subject => '' } )
99 assert_nil post.reload.attributes['subject']
100 assert_equal 'foo', post.subject
103 test "validates presence of :subject" do
107 post = Post.new :subject => 'foo'
111 test "returns the value for the correct locale, after locale switching" do
112 post = Post.create :subject => 'foo'
113 I18n.locale = 'de-DE'
116 I18n.locale = 'en-US'
118 assert_equal 'foo', post.subject
119 I18n.locale = 'de-DE'
120 assert_equal 'bar', post.subject
123 test "keeping one field in new locale when other field is changed" do
124 I18n.fallbacks.map 'de-DE' => [ 'en-US' ]
125 post = Post.create :subject => 'foo'
126 I18n.locale = 'de-DE'
128 assert_equal 'foo', post.subject
131 test "modifying non-required field in a new locale" do
132 I18n.fallbacks.map 'de-DE' => [ 'en-US' ]
133 post = Post.create :subject => 'foo'
134 I18n.locale = 'de-DE'
139 test "returns the value for the correct locale, after locale switching, without saving" do
140 post = Post.create :subject => 'foo'
141 I18n.locale = 'de-DE'
143 I18n.locale = 'en-US'
144 assert_equal 'foo', post.subject
145 I18n.locale = 'de-DE'
146 assert_equal 'bar', post.subject
149 test "saves all locales, even after locale switching" do
150 post = Post.new :subject => 'foo'
151 I18n.locale = 'de-DE'
153 I18n.locale = 'he-IL'
156 I18n.locale = 'en-US'
158 assert_equal 'foo', post.subject
159 I18n.locale = 'de-DE'
160 assert_equal 'bar', post.subject
161 I18n.locale = 'he-IL'
162 assert_equal 'baz', post.subject
165 test "resolves a simple fallback" do
166 I18n.locale = 'de-DE'
167 post = Post.create :subject => 'foo'
172 I18n.locale = 'de-DE'
173 assert_equal 'foo', post.subject
174 assert_equal 'bar', post.content
177 test "resolves a simple fallback without reloading" do
178 I18n.locale = 'de-DE'
179 post = Post.new :subject => 'foo'
183 I18n.locale = 'de-DE'
184 assert_equal 'foo', post.subject
185 assert_equal 'bar', post.content
188 test "resolves a complex fallback without reloading" do
189 I18n.fallbacks.map 'de' => %w(en he)
198 assert_equal 'foo', post.subject
199 assert_equal 'bar', post.content
202 test "returns nil if no translations are found" do
203 post = Post.new :subject => 'foo'
204 assert_equal 'foo', post.subject
205 assert_nil post.content
208 test "returns nil if no translations are found; reloaded" do
209 post = Post.create :subject => 'foo'
211 assert_equal 'foo', post.subject
212 assert_nil post.content
215 test "works with associations" do
217 post1 = blog.posts.create :subject => 'foo'
218 I18n.locale = 'de-DE'
219 post2 = blog.posts.create :subject => 'bar'
220 assert_equal 2, blog.posts.size
221 I18n.locale = 'en-US'
222 assert_equal 'foo', blog.posts.first.subject
223 assert_nil blog.posts.last.subject
224 I18n.locale = 'de-DE'
225 assert_equal 'bar', blog.posts.last.subject
228 test "works with simple dynamic finders" do
229 foo = Post.create :subject => 'foo'
230 Post.create :subject => 'bar'
231 post = Post.find_by_subject('foo')
232 assert_equal foo, post
235 test 'change attribute on globalized model' do
236 post = Post.create :subject => 'foo', :content => 'bar'
237 assert_equal [], post.changed
239 assert_equal [ 'subject' ], post.changed
240 post.content = 'quux'
241 assert_member 'subject', post.changed
242 assert_member 'content', post.changed
245 test 'change attribute on globalized model after locale switching' do
246 post = Post.create :subject => 'foo', :content => 'bar'
247 assert_equal [], post.changed
250 assert_equal [ 'subject' ], post.changed
253 test 'fallbacks with lots of locale switching' do
254 I18n.fallbacks.map :'de-DE' => [ :'en-US' ]
255 post = Post.create :subject => 'foo'
257 I18n.locale = :'de-DE'
258 assert_equal 'foo', post.subject
260 I18n.locale = :'en-US'
261 post.update_attribute :subject, 'bar'
263 I18n.locale = :'de-DE'
264 assert_equal 'bar', post.subject
268 post = Post.create :subject => 'foo', :content => 'bar'
270 assert_equal 'foo', post.reload.subject
273 test 'complex writing and stashing' do
274 post = Post.create :subject => 'foo', :content => 'bar'
276 assert_nil post.subject
280 test 'translated class locale setting' do
281 assert ActiveRecord::Base.respond_to?(:locale)
282 assert_equal :'en-US', I18n.locale
283 assert_equal :'en-US', ActiveRecord::Base.locale
285 assert_equal :de, I18n.locale
286 assert_equal :de, ActiveRecord::Base.locale
287 ActiveRecord::Base.locale = :es
288 assert_equal :de, I18n.locale
289 assert_equal :es, ActiveRecord::Base.locale
291 assert_equal :fr, I18n.locale
292 assert_equal :es, ActiveRecord::Base.locale
295 test "untranslated class responds to locale" do
296 assert Blog.respond_to?(:locale)
299 test "to ensure locales in different classes are the same" do
300 ActiveRecord::Base.locale = :de
301 assert_equal :de, ActiveRecord::Base.locale
302 assert_equal :de, Parent.locale
304 assert_equal :es, ActiveRecord::Base.locale
305 assert_equal :es, Parent.locale
308 test "attribute saving goes by content locale and not global locale" do
309 ActiveRecord::Base.locale = :de
310 assert_equal :'en-US', I18n.locale
311 Post.create :subject => 'foo'
312 assert_equal :de, Post.first.globalize_translations.first.locale
315 test "attribute loading goes by content locale and not global locale" do
316 post = Post.create :subject => 'foo'
317 assert_equal :'en-US', ActiveRecord::Base.locale
318 ActiveRecord::Base.locale = :de
319 assert_equal :'en-US', I18n.locale
320 post.update_attribute :subject, 'foo [de]'
321 assert_equal 'foo [de]', Post.first.subject
322 ActiveRecord::Base.locale = :'en-US'
323 assert_equal 'foo', Post.first.subject
326 test "access content locale before setting" do
327 Globalize::Model::ActiveRecord::Translated::ActMethods.class_eval "remove_class_variable(:@@locale)"
328 assert_nothing_raised { ActiveRecord::Base.locale }
331 test "translated_locales" do
333 post = Post.create :subject => 'foo'
335 post.update_attribute :subject, 'bar'
337 post.update_attribute :subject, 'baz'
338 assert_equal [ :de, :es, :fr ], post.translated_locales
339 assert_equal [ :de, :es, :fr ], Post.first.translated_locales
342 test "including globalize_translations" do
344 Post.create :subject => "Foo1", :content => "Bar1"
345 Post.create :subject => "Foo2", :content => "Bar2"
348 def tranlsations_included
349 self.all(:include => :globalize_translations)
353 default = Post.all.map {|x| [x.subject, x.content]}
354 with_include = Post.tranlsations_included.map {|x| [x.subject, x.content]}
355 assert_equal default, with_include
358 test "setting multiple translations at once with options hash" do
360 post = Post.create :subject => "foo1", :content => "foo1"
362 post.update_attributes( :subject => "bar1", :content => "bar1" )
364 options = { :de => {:subject => "foo2", :content => "foo2"},
365 :en => {:subject => "bar2", :content => "bar2"} }
366 post.set_translations options
369 assert ["bar2", "bar2"], [post.subject, post.content]
371 assert ["foo2", "foo2"], [post.subject, post.content]
374 test "setting only one translation with set_translations" do
376 post = Post.create :subject => "foo1", :content => "foo1"
378 post.update_attributes( :subject => "bar1", :content => "bar1" )
380 options = { :en => {:subject => "bar2", :content => "bar2"} }
381 post.set_translations options
384 assert ["bar2", "bar2"], [post.subject, post.content]
386 assert ["foo1", "foo1"], [post.subject, post.content]
389 test "setting only selected attributes with set_translations" do
391 post = Post.create :subject => "foo1", :content => "foo1"
393 post.update_attributes( :subject => "bar1", :content => "bar1" )
395 options = { :de => {:content => "foo2"}, :en => {:subject => "bar2"} }
396 post.set_translations options
399 assert ["bar2", "bar1"], [post.subject, post.content]
401 assert ["foo1", "foo2"], [post.subject, post.content]
404 test "setting invalid attributes raises ArgumentError" do
406 post = Post.create :subject => "foo1", :content => "foo1"
408 post.update_attributes( :subject => "bar1", :content => "bar1" )
410 options = { :de => {:fake => "foo2"} }
411 exception = assert_raise(ActiveRecord::UnknownAttributeError) do
412 post.set_translations options
414 assert_equal "unknown attribute: fake", exception.message
417 test "reload accepting find options" do
418 p = Post.create :subject => "Foo", :content => "Bar"
419 assert p.reload(:readonly => true, :lock => true)
420 assert_raise(ArgumentError) { p.reload(:foo => :bar) }
423 test "dependent destroy of translation" do
424 p = Post.create :subject => "Foo", :content => "Bar"
425 assert_equal 1, PostTranslation.count
427 assert_equal 0, PostTranslation.count
430 test "translating subclass of untranslated comment model" do
431 translated_comment = TranslatedComment.create(:post => @post)
432 assert_nothing_raised { translated_comment.globalize_translations }
435 test "modifiying translated comments works as expected" do
437 translated_comment = TranslatedComment.create(:post => @post, :content => 'foo')
438 assert_equal 'foo', translated_comment.content
441 translated_comment.content = 'bar'
442 assert translated_comment.save
443 assert_equal 'bar', translated_comment.content
446 assert_equal 'foo', translated_comment.content
448 assert_equal 2, translated_comment.globalize_translations.size
452 # TODO should validate_presence_of take fallbacks into account? maybe we need
453 # an extra validation call, or more options for validate_presence_of.
454 # TODO error checking for fields that exist in main table, don't exist in
455 # proxy table, aren't strings or text
457 # TODO allow finding by translated attributes in conditions?
458 # TODO generate advanced dynamic finders?