aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/test/cases/observer_array_test.rb
blob: 38e4fd59fc019f8d3d5dc83ddc02081ec32432df (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
require 'cases/helper'
require 'models/observers'

class ObserverArrayTest < ActiveModel::TestCase
  def teardown
    ORM.observers.enable :all
    Budget.observers.enable :all
    Widget.observers.enable :all
  end

  def assert_observer_notified(model_class, observer_class)
    observer_class.instance.before_save_invocations.clear
    model_instance = model_class.new
    model_instance.save
    assert_equal [model_instance], observer_class.instance.before_save_invocations
  end

  def assert_observer_not_notified(model_class, observer_class)
    observer_class.instance.before_save_invocations.clear
    model_instance = model_class.new
    model_instance.save
    assert_equal [], observer_class.instance.before_save_invocations
  end

  test "all observers are enabled by default" do
    assert_observer_notified Widget, WidgetObserver
    assert_observer_notified Budget, BudgetObserver
    assert_observer_notified Widget, AuditTrail
    assert_observer_notified Budget, AuditTrail
  end

  test "can disable individual observers using a class constant" do
    ORM.observers.disable WidgetObserver

    assert_observer_not_notified Widget, WidgetObserver
    assert_observer_notified     Budget, BudgetObserver
    assert_observer_notified     Widget, AuditTrail
    assert_observer_notified     Budget, AuditTrail
  end

  test "can disable individual observers using a symbol" do
    ORM.observers.disable :budget_observer

    assert_observer_notified     Widget, WidgetObserver
    assert_observer_not_notified Budget, BudgetObserver
    assert_observer_notified     Widget, AuditTrail
    assert_observer_notified     Budget, AuditTrail
  end

  test "can disable all observers using :all" do
    ORM.observers.disable :all

    assert_observer_not_notified Widget, WidgetObserver
    assert_observer_not_notified Budget, BudgetObserver
    assert_observer_not_notified Widget, AuditTrail
    assert_observer_not_notified Budget, AuditTrail
  end

  test "can disable observers on individual models without affecting observers on other models" do
    Widget.observers.disable :all

    assert_observer_not_notified Widget, WidgetObserver
    assert_observer_notified     Budget, BudgetObserver
    assert_observer_not_notified Widget, AuditTrail
    assert_observer_notified     Budget, AuditTrail
  end

  test "can disable observers for the duration of a block" do
    yielded = false
    ORM.observers.disable :budget_observer do
      yielded = true
      assert_observer_notified     Widget, WidgetObserver
      assert_observer_not_notified Budget, BudgetObserver
      assert_observer_notified     Widget, AuditTrail
      assert_observer_notified     Budget, AuditTrail
    end

    assert yielded
    assert_observer_notified Widget, WidgetObserver
    assert_observer_notified Budget, BudgetObserver
    assert_observer_notified Widget, AuditTrail
    assert_observer_notified Budget, AuditTrail
  end

  test "can enable observers for the duration of a block" do
    yielded = false
    Widget.observers.disable :all

    Widget.observers.enable :all do
      yielded = true
      assert_observer_notified Widget, WidgetObserver
      assert_observer_notified Budget, BudgetObserver
      assert_observer_notified Widget, AuditTrail
      assert_observer_notified Budget, AuditTrail
    end

    assert yielded
    assert_observer_not_notified Widget, WidgetObserver
    assert_observer_notified     Budget, BudgetObserver
    assert_observer_not_notified Widget, AuditTrail
    assert_observer_notified     Budget, AuditTrail
  end

  test "raises an appropriate error when a developer accidentally enables or disables the wrong class (i.e. Widget instead of WidgetObserver)" do
    assert_raise ArgumentError do
      ORM.observers.enable :widget
    end

    assert_raise ArgumentError do
      ORM.observers.enable Widget
    end

    assert_raise ArgumentError do
      ORM.observers.disable :widget
    end

    assert_raise ArgumentError do
      ORM.observers.disable Widget
    end
  end

  test "allows #enable at the superclass level to override #disable at the subclass level when called last" do
    Widget.observers.disable :all
    ORM.observers.enable :all

    assert_observer_notified Widget, WidgetObserver
    assert_observer_notified Budget, BudgetObserver
    assert_observer_notified Widget, AuditTrail
    assert_observer_notified Budget, AuditTrail
  end

  test "allows #disable at the superclass level to override #enable at the subclass level when called last" do
    Budget.observers.enable :audit_trail
    ORM.observers.disable :audit_trail

    assert_observer_notified     Widget, WidgetObserver
    assert_observer_notified     Budget, BudgetObserver
    assert_observer_not_notified Widget, AuditTrail
    assert_observer_not_notified Budget, AuditTrail
  end

  test "can use the block form at different levels of the hierarchy" do
    yielded = false
    Widget.observers.disable :all

    ORM.observers.enable :all do
      yielded = true
      assert_observer_notified Widget, WidgetObserver
      assert_observer_notified Budget, BudgetObserver
      assert_observer_notified Widget, AuditTrail
      assert_observer_notified Budget, AuditTrail
    end

    assert yielded
    assert_observer_not_notified Widget, WidgetObserver
    assert_observer_notified     Budget, BudgetObserver
    assert_observer_not_notified Widget, AuditTrail
    assert_observer_notified     Budget, AuditTrail
  end
end