2009-09-08 15:10:14 +00:00
require 'cases/helper'
2008-01-18 07:31:37 +00:00
require 'models/topic'
require 'models/developer'
require 'models/reply'
2008-06-09 03:45:57 +00:00
require 'models/minimalistic'
2010-04-16 14:20:31 +00:00
require 'models/comment'
2004-11-24 01:04:44 +00:00
2005-09-19 16:34:34 +00:00
class SpecialDeveloper < Developer ; end
2004-11-24 01:04:44 +00:00
2010-04-16 17:30:40 +00:00
class SalaryChecker < ActiveRecord :: Observer
observe :special_developer
2010-11-26 18:16:13 +00:00
attr_accessor :last_saved
2010-04-16 17:30:40 +00:00
def before_save ( developer )
return developer . salary > 80000
end
2010-11-26 18:16:13 +00:00
module Implementation
def after_save ( developer )
self . last_saved = developer
end
end
include Implementation
2010-04-16 17:30:40 +00:00
end
2008-02-17 22:52:55 +00:00
class TopicaAuditor < ActiveRecord :: Observer
2007-10-14 05:20:24 +00:00
observe :topic
2008-01-18 07:30:42 +00:00
2004-11-24 01:04:44 +00:00
attr_reader :topic
2008-01-18 07:30:42 +00:00
2004-11-24 01:04:44 +00:00
def after_find ( topic )
@topic = topic
end
end
class TopicObserver < ActiveRecord :: Observer
attr_reader :topic
2008-01-18 07:30:42 +00:00
2004-11-24 01:04:44 +00:00
def after_find ( topic )
@topic = topic
end
2009-09-08 15:10:14 +00:00
# Create an after_save callback, so a notify_observer hook is created
# on :topic.
def after_save ( nothing )
end
2004-11-24 01:04:44 +00:00
end
2008-06-09 03:45:57 +00:00
class MinimalisticObserver < ActiveRecord :: Observer
attr_reader :minimalistic
def after_find ( minimalistic )
@minimalistic = minimalistic
end
end
2004-11-24 01:04:44 +00:00
class MultiObserver < ActiveRecord :: Observer
attr_reader :record
2006-06-30 04:38:24 +00:00
2004-11-24 01:04:44 +00:00
def self . observed_class ( ) [ Topic , Developer ] end
2006-06-30 04:38:24 +00:00
cattr_reader :last_inherited
@@last_inherited = nil
def observed_class_inherited_with_testing ( subclass )
observed_class_inherited_without_testing ( subclass )
@@last_inherited = subclass
end
alias_method_chain :observed_class_inherited , :testing
2004-11-24 01:04:44 +00:00
def after_find ( record )
@record = record
end
end
2010-04-16 14:20:31 +00:00
class ValidatedComment < Comment
attr_accessor :callers
before_validation :record_callers
after_validation do
record_callers
end
def record_callers
callers << self . class if callers
end
end
class ValidatedCommentObserver < ActiveRecord :: Observer
attr_accessor :callers
def after_validation ( model )
callers << self . class if callers
end
end
2008-01-21 17:20:51 +00:00
class LifecycleTest < ActiveRecord :: TestCase
2008-07-31 20:59:53 +00:00
fixtures :topics , :developers , :minimalistics
2004-11-24 01:04:44 +00:00
def test_before_destroy
2010-12-30 20:41:02 +00:00
topic = Topic . find ( 1 )
assert_difference 'Topic.count' , - ( 1 + topic . replies . size ) do
topic . destroy
end
2004-11-24 01:04:44 +00:00
end
2006-06-30 04:38:24 +00:00
2004-11-24 01:04:44 +00:00
def test_auto_observer
2008-02-17 22:52:55 +00:00
topic_observer = TopicaAuditor . instance
assert_nil TopicaAuditor . observed_class
assert_equal [ Topic ] , TopicaAuditor . instance . observed_classes . to_a
2004-11-24 01:04:44 +00:00
2006-06-30 04:38:24 +00:00
topic = Topic . find ( 1 )
assert_equal topic . title , topic_observer . topic . title
2004-11-24 01:04:44 +00:00
end
2006-06-30 04:38:24 +00:00
def test_inferred_auto_observer
2004-11-24 01:04:44 +00:00
topic_observer = TopicObserver . instance
2008-02-17 22:52:55 +00:00
assert_equal Topic , TopicObserver . observed_class
2004-11-24 01:04:44 +00:00
2006-06-30 04:38:24 +00:00
topic = Topic . find ( 1 )
assert_equal topic . title , topic_observer . topic . title
2004-11-24 01:04:44 +00:00
end
2006-06-30 04:38:24 +00:00
2004-11-24 01:04:44 +00:00
def test_observing_two_classes
multi_observer = MultiObserver . instance
topic = Topic . find ( 1 )
2006-06-30 04:38:24 +00:00
assert_equal topic . title , multi_observer . record . title
2004-11-24 01:04:44 +00:00
2006-06-30 04:38:24 +00:00
developer = Developer . find ( 1 )
assert_equal developer . name , multi_observer . record . name
2004-11-24 01:04:44 +00:00
end
2006-06-30 04:38:24 +00:00
2005-09-19 16:34:34 +00:00
def test_observing_subclasses
multi_observer = MultiObserver . instance
developer = SpecialDeveloper . find ( 1 )
2006-06-30 04:38:24 +00:00
assert_equal developer . name , multi_observer . record . name
klass = Class . new ( Developer )
assert_equal klass , multi_observer . last_inherited
developer = klass . find ( 1 )
assert_equal developer . name , multi_observer . record . name
end
2008-07-22 20:38:26 +00:00
def test_after_find_can_be_observed_when_its_not_defined_on_the_model
2008-06-09 03:45:57 +00:00
observer = MinimalisticObserver . instance
assert_equal Minimalistic , MinimalisticObserver . observed_class
minimalistic = Minimalistic . find ( 1 )
2008-07-22 20:38:26 +00:00
assert_equal minimalistic , observer . minimalistic
2008-07-15 18:55:14 +00:00
end
def test_after_find_can_be_observed_when_its_defined_on_the_model
observer = TopicObserver . instance
assert_equal Topic , TopicObserver . observed_class
topic = Topic . find ( 1 )
assert_equal topic , observer . topic
2008-06-09 03:45:57 +00:00
end
2006-06-30 04:38:24 +00:00
def test_invalid_observer
2006-08-06 02:40:24 +00:00
assert_raise ( ArgumentError ) { Topic . observers = Object . new ; Topic . instantiate_observers }
2005-09-19 16:34:34 +00:00
end
2010-04-16 14:20:31 +00:00
test " model callbacks fire before observers are notified " do
callers = [ ]
comment = ValidatedComment . new
comment . callers = ValidatedCommentObserver . instance . callers = callers
comment . valid?
assert_equal [ ValidatedComment , ValidatedComment , ValidatedCommentObserver ] , callers ,
" model callbacks did not fire before observers were notified "
end
2010-04-16 17:30:40 +00:00
test " able to save developer " do
SalaryChecker . instance # activate
developer = SpecialDeveloper . new :name = > 'Roger' , :salary = > 100000
assert developer . save , " developer with normal salary failed to save "
end
test " unable to save developer with low salary " do
SalaryChecker . instance # activate
developer = SpecialDeveloper . new :name = > 'Rookie' , :salary = > 50000
assert ! developer . save , " allowed to save a developer with too low salary "
end
2010-11-26 18:16:13 +00:00
test " able to call methods defined with included module " do # https://rails.lighthouseapp.com/projects/8994/tickets/6065-activerecordobserver-is-not-aware-of-method-added-by-including-modules
SalaryChecker . instance # activate
developer = SpecialDeveloper . create! :name = > 'Roger' , :salary = > 100000
assert_equal developer , SalaryChecker . instance . last_saved
end
2005-06-10 14:58:02 +00:00
end