aasm 3.0.26 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +9 -1
- data/README.md +56 -4
- data/aasm.gemspec +1 -1
- data/lib/aasm/base.rb +21 -15
- data/lib/aasm/event.rb +15 -4
- data/lib/aasm/instance_base.rb +2 -0
- data/lib/aasm/persistence/active_record_persistence.rb +17 -1
- data/lib/aasm/transition.rb +13 -6
- data/lib/aasm/version.rb +1 -1
- data/spec/models/guardian.rb +48 -0
- data/spec/unit/api_spec.rb +12 -12
- data/spec/unit/callbacks_spec.rb +25 -25
- data/spec/unit/complex_example_spec.rb +15 -15
- data/spec/unit/event_spec.rb +44 -44
- data/spec/unit/guard_spec.rb +60 -0
- data/spec/unit/initial_state_spec.rb +3 -3
- data/spec/unit/inspection_spec.rb +36 -36
- data/spec/unit/localizer_spec.rb +12 -12
- data/spec/unit/new_dsl_spec.rb +2 -2
- data/spec/unit/persistence/active_record_persistence_spec.rb +107 -67
- data/spec/unit/persistence/mongoid_persistance_spec.rb +24 -24
- data/spec/unit/simple_example_spec.rb +20 -20
- data/spec/unit/state_spec.rb +16 -16
- data/spec/unit/subclassing_spec.rb +6 -6
- data/spec/unit/transition_spec.rb +55 -40
- metadata +8 -4
data/spec/unit/callbacks_spec.rb
CHANGED
@@ -4,15 +4,15 @@ describe 'callbacks for the new DSL' do
|
|
4
4
|
let(:callback) {CallbackNewDsl.new}
|
5
5
|
|
6
6
|
it "be called in order" do
|
7
|
-
callback.
|
8
|
-
callback.
|
9
|
-
callback.
|
10
|
-
callback.
|
11
|
-
callback.
|
12
|
-
callback.
|
13
|
-
callback.
|
14
|
-
callback.
|
15
|
-
callback.
|
7
|
+
expect(callback).to receive(:exit_open).once.ordered
|
8
|
+
expect(callback).to receive(:before).once.ordered
|
9
|
+
expect(callback).to receive(:before_exit_open).once.ordered # these should be before the state changes
|
10
|
+
expect(callback).to receive(:before_enter_closed).once.ordered
|
11
|
+
expect(callback).to receive(:enter_closed).once.ordered
|
12
|
+
expect(callback).to receive(:aasm_write_state).once.ordered.and_return(true) # this is when the state changes
|
13
|
+
expect(callback).to receive(:after_exit_open).once.ordered # these should be after the state changes
|
14
|
+
expect(callback).to receive(:after_enter_closed).once.ordered
|
15
|
+
expect(callback).to receive(:after).once.ordered
|
16
16
|
|
17
17
|
callback.close!
|
18
18
|
end
|
@@ -35,20 +35,20 @@ describe 'event callbacks' do
|
|
35
35
|
it "should run error_callback if an exception is raised and error_callback defined" do
|
36
36
|
def @foo.error_callback(e); end
|
37
37
|
|
38
|
-
@foo.
|
39
|
-
@foo.
|
38
|
+
allow(@foo).to receive(:enter).and_raise(e=StandardError.new)
|
39
|
+
expect(@foo).to receive(:error_callback).with(e)
|
40
40
|
|
41
41
|
@foo.safe_close!
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should raise NoMethodError if exceptionis raised and error_callback is declared but not defined" do
|
45
|
-
@foo.
|
46
|
-
|
45
|
+
allow(@foo).to receive(:enter).and_raise(StandardError)
|
46
|
+
expect{@foo.safe_close!}.to raise_error(NoMethodError)
|
47
47
|
end
|
48
48
|
|
49
49
|
it "should propagate an error if no error callback is declared" do
|
50
|
-
@foo.
|
51
|
-
|
50
|
+
allow(@foo).to receive(:enter).and_raise("Cannot enter safe")
|
51
|
+
expect{@foo.close!}.to raise_error(StandardError, "Cannot enter safe")
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -59,18 +59,18 @@ describe 'event callbacks' do
|
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'should call it for successful bang fire' do
|
62
|
-
@foo.
|
62
|
+
expect(@foo).to receive(:aasm_event_fired).with(:close, :open, :closed)
|
63
63
|
@foo.close!
|
64
64
|
end
|
65
65
|
|
66
66
|
it 'should call it for successful non-bang fire' do
|
67
|
-
@foo.
|
67
|
+
expect(@foo).to receive(:aasm_event_fired)
|
68
68
|
@foo.close
|
69
69
|
end
|
70
70
|
|
71
71
|
it 'should not call it for failing bang fire' do
|
72
|
-
@foo.aasm.
|
73
|
-
@foo.
|
72
|
+
allow(@foo.aasm).to receive(:set_current_state_with_persistence).and_return(false)
|
73
|
+
expect(@foo).not_to receive(:aasm_event_fired)
|
74
74
|
@foo.close!
|
75
75
|
end
|
76
76
|
end
|
@@ -82,18 +82,18 @@ describe 'event callbacks' do
|
|
82
82
|
end
|
83
83
|
|
84
84
|
it 'should call it when transition failed for bang fire' do
|
85
|
-
@foo.
|
86
|
-
|
85
|
+
expect(@foo).to receive(:aasm_event_failed).with(:null, :open)
|
86
|
+
expect {@foo.null!}.to raise_error(AASM::InvalidTransition)
|
87
87
|
end
|
88
88
|
|
89
89
|
it 'should call it when transition failed for non-bang fire' do
|
90
|
-
@foo.
|
91
|
-
|
90
|
+
expect(@foo).to receive(:aasm_event_failed).with(:null, :open)
|
91
|
+
expect {@foo.null}.to raise_error(AASM::InvalidTransition)
|
92
92
|
end
|
93
93
|
|
94
94
|
it 'should not call it if persist fails for bang fire' do
|
95
|
-
@foo.aasm.
|
96
|
-
@foo.
|
95
|
+
allow(@foo.aasm).to receive(:set_current_state_with_persistence).and_return(false)
|
96
|
+
expect(@foo).to receive(:aasm_event_failed)
|
97
97
|
@foo.close!
|
98
98
|
end
|
99
99
|
end
|
@@ -4,12 +4,12 @@ describe 'on initialization' do
|
|
4
4
|
let(:auth) {AuthMachine.new}
|
5
5
|
|
6
6
|
it 'should be in the pending state' do
|
7
|
-
auth.aasm.current_state.
|
7
|
+
expect(auth.aasm.current_state).to eq(:pending)
|
8
8
|
end
|
9
9
|
|
10
10
|
it 'should have an activation code' do
|
11
|
-
auth.has_activation_code
|
12
|
-
auth.activation_code.
|
11
|
+
expect(auth.has_activation_code?).to be_true
|
12
|
+
expect(auth.activation_code).not_to be_nil
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -19,26 +19,26 @@ describe 'when being unsuspended' do
|
|
19
19
|
it 'should be able to be unsuspended' do
|
20
20
|
auth.activate!
|
21
21
|
auth.suspend!
|
22
|
-
auth.may_unsuspend
|
22
|
+
expect(auth.may_unsuspend?).to be_true
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'should not be able to be unsuspended into active' do
|
26
26
|
auth.suspend!
|
27
|
-
auth.may_unsuspend?(:active).
|
27
|
+
expect(auth.may_unsuspend?(:active)).not_to be_true
|
28
28
|
end
|
29
29
|
|
30
30
|
it 'should be able to be unsuspended into active if polite' do
|
31
31
|
auth.suspend!
|
32
|
-
auth.may_wait?(:waiting, :please).
|
32
|
+
expect(auth.may_wait?(:waiting, :please)).to be_true
|
33
33
|
auth.wait!(nil, :please)
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'should not be able to be unsuspended into active if not polite' do
|
37
37
|
auth.suspend!
|
38
|
-
auth.may_wait?(:waiting).
|
39
|
-
auth.may_wait?(:waiting, :rude).
|
40
|
-
|
41
|
-
|
38
|
+
expect(auth.may_wait?(:waiting)).not_to be_true
|
39
|
+
expect(auth.may_wait?(:waiting, :rude)).not_to be_true
|
40
|
+
expect {auth.wait!(nil, :rude)}.to raise_error(AASM::InvalidTransition)
|
41
|
+
expect {auth.wait!}.to raise_error(AASM::InvalidTransition)
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'should not be able to be unpassified' do
|
@@ -46,8 +46,8 @@ describe 'when being unsuspended' do
|
|
46
46
|
auth.suspend!
|
47
47
|
auth.unsuspend!
|
48
48
|
|
49
|
-
auth.may_unpassify
|
50
|
-
|
49
|
+
expect(auth.may_unpassify?).not_to be_true
|
50
|
+
expect {auth.unpassify!}.to raise_error(AASM::InvalidTransition)
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'should be active if previously activated' do
|
@@ -55,14 +55,14 @@ describe 'when being unsuspended' do
|
|
55
55
|
auth.suspend!
|
56
56
|
auth.unsuspend!
|
57
57
|
|
58
|
-
auth.aasm.current_state.
|
58
|
+
expect(auth.aasm.current_state).to eq(:active)
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'should be pending if not previously activated, but an activation code is present' do
|
62
62
|
auth.suspend!
|
63
63
|
auth.unsuspend!
|
64
64
|
|
65
|
-
auth.aasm.current_state.
|
65
|
+
expect(auth.aasm.current_state).to eq(:pending)
|
66
66
|
end
|
67
67
|
|
68
68
|
it 'should be passive if not previously activated and there is no activation code' do
|
@@ -70,6 +70,6 @@ describe 'when being unsuspended' do
|
|
70
70
|
auth.suspend!
|
71
71
|
auth.unsuspend!
|
72
72
|
|
73
|
-
auth.aasm.current_state.
|
73
|
+
expect(auth.aasm.current_state).to eq(:passive)
|
74
74
|
end
|
75
75
|
end
|
data/spec/unit/event_spec.rb
CHANGED
@@ -10,27 +10,27 @@ describe 'adding an event' do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'should set the name' do
|
13
|
-
event.name.
|
13
|
+
expect(event.name).to eq(:close_order)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should set the success callback' do
|
17
|
-
event.options[:success].
|
17
|
+
expect(event.options[:success]).to eq(:success_callback)
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'should set the after callback' do
|
21
|
-
event.options[:after].
|
21
|
+
expect(event.options[:after]).to eq([:after_callback])
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'should set the before callback' do
|
25
|
-
event.options[:before].
|
25
|
+
expect(event.options[:before]).to eq([:before_callback])
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'should create transitions' do
|
29
29
|
transitions = event.transitions
|
30
|
-
transitions[0].from.
|
31
|
-
transitions[0].to.
|
32
|
-
transitions[1].from.
|
33
|
-
transitions[1].to.
|
30
|
+
expect(transitions[0].from).to eq(:open)
|
31
|
+
expect(transitions[0].to).to eq(:closed)
|
32
|
+
expect(transitions[1].from).to eq(:received)
|
33
|
+
expect(transitions[1].to).to eq(:closed)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -42,19 +42,19 @@ describe 'transition inspection' do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'should support inspecting transitions from other states' do
|
45
|
-
event.transitions_from_state(:sleeping).map(&:to).
|
46
|
-
event.transitions_from_state?(:sleeping).
|
45
|
+
expect(event.transitions_from_state(:sleeping).map(&:to)).to eq([:running])
|
46
|
+
expect(event.transitions_from_state?(:sleeping)).to be_true
|
47
47
|
|
48
|
-
event.transitions_from_state(:cleaning).map(&:to).
|
49
|
-
event.transitions_from_state?(:cleaning).
|
48
|
+
expect(event.transitions_from_state(:cleaning).map(&:to)).to eq([])
|
49
|
+
expect(event.transitions_from_state?(:cleaning)).to be_false
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'should support inspecting transitions to other states' do
|
53
|
-
event.transitions_to_state(:running).map(&:from).
|
54
|
-
event.transitions_to_state?(:running).
|
53
|
+
expect(event.transitions_to_state(:running).map(&:from)).to eq([:sleeping])
|
54
|
+
expect(event.transitions_to_state?(:running)).to be_true
|
55
55
|
|
56
|
-
event.transitions_to_state(:cleaning).map(&:to).
|
57
|
-
event.transitions_to_state?(:cleaning).
|
56
|
+
expect(event.transitions_to_state(:cleaning).map(&:to)).to eq([])
|
57
|
+
expect(event.transitions_to_state?(:cleaning)).to be_false
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -63,7 +63,7 @@ describe 'firing an event' do
|
|
63
63
|
obj = double('object', :aasm => double('aasm', :current_state => 'open'))
|
64
64
|
|
65
65
|
event = AASM::Event.new(:event)
|
66
|
-
event.fire(obj).
|
66
|
+
expect(event.fire(obj)).to be_nil
|
67
67
|
end
|
68
68
|
|
69
69
|
it 'should return the state of the first matching transition it finds' do
|
@@ -73,7 +73,7 @@ describe 'firing an event' do
|
|
73
73
|
|
74
74
|
obj = double('object', :aasm => double('aasm', :current_state => :open))
|
75
75
|
|
76
|
-
event.fire(obj).
|
76
|
+
expect(event.fire(obj)).to eq(:closed)
|
77
77
|
end
|
78
78
|
|
79
79
|
it 'should call the guard with the params passed in' do
|
@@ -82,9 +82,9 @@ describe 'firing an event' do
|
|
82
82
|
end
|
83
83
|
|
84
84
|
obj = double('object', :aasm => double('aasm', :current_state => :open))
|
85
|
-
obj.
|
85
|
+
expect(obj).to receive(:guard_fn).with('arg1', 'arg2').and_return(true)
|
86
86
|
|
87
|
-
event.fire(obj, nil, 'arg1', 'arg2').
|
87
|
+
expect(event.fire(obj, nil, 'arg1', 'arg2')).to eq(:closed)
|
88
88
|
end
|
89
89
|
|
90
90
|
end
|
@@ -101,7 +101,7 @@ describe 'should fire callbacks' do
|
|
101
101
|
}
|
102
102
|
|
103
103
|
model = ThisNameBetterNotBeInUse.new
|
104
|
-
model.
|
104
|
+
expect(model).to receive(:symbol_success_callback)
|
105
105
|
model.with_symbol!
|
106
106
|
end
|
107
107
|
|
@@ -115,7 +115,7 @@ describe 'should fire callbacks' do
|
|
115
115
|
}
|
116
116
|
|
117
117
|
model = ThisNameBetterNotBeInUse.new
|
118
|
-
model.
|
118
|
+
expect(model).to receive(:string_success_callback)
|
119
119
|
model.with_string!
|
120
120
|
end
|
121
121
|
|
@@ -129,8 +129,8 @@ describe 'should fire callbacks' do
|
|
129
129
|
}
|
130
130
|
|
131
131
|
model = ThisNameBetterNotBeInUse.new
|
132
|
-
model.
|
133
|
-
model.
|
132
|
+
expect(model).to receive(:success_callback1)
|
133
|
+
expect(model).to receive(:success_callback2)
|
134
134
|
model.with_array!
|
135
135
|
end
|
136
136
|
|
@@ -144,9 +144,9 @@ describe 'should fire callbacks' do
|
|
144
144
|
}
|
145
145
|
|
146
146
|
model = ThisNameBetterNotBeInUse.new
|
147
|
-
model.
|
148
|
-
model.
|
149
|
-
model.
|
147
|
+
expect(model).to receive(:success_callback1)
|
148
|
+
expect(model).to receive(:success_callback2)
|
149
|
+
expect(model).to receive(:proc_success_callback)
|
150
150
|
model.with_array_including_procs!
|
151
151
|
end
|
152
152
|
|
@@ -160,7 +160,7 @@ describe 'should fire callbacks' do
|
|
160
160
|
}
|
161
161
|
|
162
162
|
model = ThisNameBetterNotBeInUse.new
|
163
|
-
model.
|
163
|
+
expect(model).to receive(:proc_success_callback)
|
164
164
|
model.with_proc!
|
165
165
|
end
|
166
166
|
end
|
@@ -182,9 +182,9 @@ describe 'should fire callbacks' do
|
|
182
182
|
end
|
183
183
|
|
184
184
|
model = ThisNameBetterNotBeInUse.new
|
185
|
-
model.
|
186
|
-
model.
|
187
|
-
model.
|
185
|
+
expect(model).to receive(:do_one_thing_after).once.ordered
|
186
|
+
expect(model).to receive(:do_another_thing_after_too).once.ordered
|
187
|
+
expect(model).to receive(:do_third_thing_at_last).once.ordered
|
188
188
|
model.with_afters!
|
189
189
|
end
|
190
190
|
end
|
@@ -203,7 +203,7 @@ describe 'should fire callbacks' do
|
|
203
203
|
end
|
204
204
|
|
205
205
|
model = ThisNameBetterNotBeInUse.new
|
206
|
-
model.
|
206
|
+
expect(model).to receive(:do_something_before).once
|
207
207
|
model.before_as_proc!
|
208
208
|
end
|
209
209
|
end
|
@@ -221,8 +221,8 @@ describe 'should fire callbacks' do
|
|
221
221
|
end
|
222
222
|
|
223
223
|
model = ThisNameBetterNotBeInUse.new
|
224
|
-
model.
|
225
|
-
model.
|
224
|
+
expect(model).to receive(:do_something_before).once.ordered
|
225
|
+
expect(model).to receive(:do_something_after).once.ordered
|
226
226
|
model.in_right_order!
|
227
227
|
end
|
228
228
|
end
|
@@ -232,40 +232,40 @@ describe 'parametrised events' do
|
|
232
232
|
|
233
233
|
it 'should transition to specified next state (sleeping to showering)' do
|
234
234
|
pe.wakeup!(:showering)
|
235
|
-
pe.aasm.current_state.
|
235
|
+
expect(pe.aasm.current_state).to eq(:showering)
|
236
236
|
end
|
237
237
|
|
238
238
|
it 'should transition to specified next state (sleeping to working)' do
|
239
239
|
pe.wakeup!(:working)
|
240
|
-
pe.aasm.current_state.
|
240
|
+
expect(pe.aasm.current_state).to eq(:working)
|
241
241
|
end
|
242
242
|
|
243
243
|
it 'should transition to default (first or showering) state' do
|
244
244
|
pe.wakeup!
|
245
|
-
pe.aasm.current_state.
|
245
|
+
expect(pe.aasm.current_state).to eq(:showering)
|
246
246
|
end
|
247
247
|
|
248
248
|
it 'should transition to default state when on_transition invoked' do
|
249
249
|
pe.dress!(nil, 'purple', 'dressy')
|
250
|
-
pe.aasm.current_state.
|
250
|
+
expect(pe.aasm.current_state).to eq(:working)
|
251
251
|
end
|
252
252
|
|
253
253
|
it 'should call on_transition method with args' do
|
254
254
|
pe.wakeup!(:showering)
|
255
|
-
pe.
|
255
|
+
expect(pe).to receive(:wear_clothes).with('blue', 'jeans')
|
256
256
|
pe.dress!(:working, 'blue', 'jeans')
|
257
257
|
end
|
258
258
|
|
259
259
|
it 'should call on_transition proc' do
|
260
260
|
pe.wakeup!(:showering)
|
261
|
-
pe.
|
261
|
+
expect(pe).to receive(:wear_clothes).with('purple', 'slacks')
|
262
262
|
pe.dress!(:dating, 'purple', 'slacks')
|
263
263
|
end
|
264
264
|
|
265
265
|
it 'should call on_transition with an array of methods' do
|
266
266
|
pe.wakeup!(:showering)
|
267
|
-
pe.
|
268
|
-
pe.
|
267
|
+
expect(pe).to receive(:condition_hair)
|
268
|
+
expect(pe).to receive(:fix_hair)
|
269
269
|
pe.dress!(:prettying_up)
|
270
270
|
end
|
271
271
|
end
|
@@ -274,9 +274,9 @@ describe 'event firing without persistence' do
|
|
274
274
|
it 'should attempt to persist if aasm_write_state is defined' do
|
275
275
|
foo = Foo.new
|
276
276
|
def foo.aasm_write_state; end
|
277
|
-
foo.
|
277
|
+
expect(foo).to be_open
|
278
278
|
|
279
|
-
foo.
|
279
|
+
expect(foo).to receive(:aasm_write_state_without_persistence)
|
280
280
|
foo.close
|
281
281
|
end
|
282
282
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "per-transition guards" do
|
4
|
+
let(:guardian) { Guardian.new }
|
5
|
+
|
6
|
+
it "allows the transition if the guard succeeds" do
|
7
|
+
expect { guardian.use_one_guard_that_succeeds! }.to_not raise_error
|
8
|
+
expect(guardian).to be_beta
|
9
|
+
end
|
10
|
+
|
11
|
+
it "stops the transition if the guard fails" do
|
12
|
+
expect { guardian.use_one_guard_that_fails! }.to raise_error(AASM::InvalidTransition)
|
13
|
+
expect(guardian).to be_alpha
|
14
|
+
end
|
15
|
+
|
16
|
+
it "allows the transition if all guards succeeds" do
|
17
|
+
expect { guardian.use_guards_that_succeed! }.to_not raise_error
|
18
|
+
expect(guardian).to be_beta
|
19
|
+
end
|
20
|
+
|
21
|
+
it "stops the transition if the first guard fails" do
|
22
|
+
expect { guardian.use_guards_where_the_first_fails! }.to raise_error(AASM::InvalidTransition)
|
23
|
+
expect(guardian).to be_alpha
|
24
|
+
end
|
25
|
+
|
26
|
+
it "stops the transition if the second guard fails" do
|
27
|
+
expect { guardian.use_guards_where_the_second_fails! }.to raise_error(AASM::InvalidTransition)
|
28
|
+
expect(guardian).to be_alpha
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "event guards" do
|
33
|
+
let(:guardian) { Guardian.new }
|
34
|
+
|
35
|
+
it "allows the transition if the event guards succeed" do
|
36
|
+
expect { guardian.use_event_guards_that_succeed! }.to_not raise_error
|
37
|
+
expect(guardian).to be_beta
|
38
|
+
end
|
39
|
+
|
40
|
+
it "allows the transition if the event and transition guards succeed" do
|
41
|
+
expect { guardian.use_event_and_transition_guards_that_succeed! }.to_not raise_error
|
42
|
+
expect(guardian).to be_beta
|
43
|
+
end
|
44
|
+
|
45
|
+
it "stops the transition if the first event guard fails" do
|
46
|
+
expect { guardian.use_event_guards_where_the_first_fails! }.to raise_error(AASM::InvalidTransition)
|
47
|
+
expect(guardian).to be_alpha
|
48
|
+
end
|
49
|
+
|
50
|
+
it "stops the transition if the second event guard fails" do
|
51
|
+
expect { guardian.use_event_guards_where_the_second_fails! }.to raise_error(AASM::InvalidTransition)
|
52
|
+
expect(guardian).to be_alpha
|
53
|
+
end
|
54
|
+
|
55
|
+
it "stops the transition if the transition guard fails" do
|
56
|
+
expect { guardian.use_event_and_transition_guards_where_third_fails! }.to raise_error(AASM::InvalidTransition)
|
57
|
+
expect(guardian).to be_alpha
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|