state_flow 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/spec/page_spec.rb ADDED
@@ -0,0 +1,554 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.join(File.dirname(__FILE__), 'spec_helper')
3
+
4
+ describe Page do
5
+ before(:each) do
6
+ StateFlow::Log.delete_all
7
+ Page.delete_all
8
+ end
9
+
10
+ describe "state_cd_by_key" do
11
+ it "each entries" do
12
+ flow = Page.state_flow_for(:status_cd)
13
+ Page.status_keys.each do |key|
14
+ flow.state_cd_by_key(key).should == Page.status_id_by_key(key)
15
+ end
16
+ end
17
+ end
18
+
19
+ describe ":created => :editable" do
20
+ it "valid" do
21
+ p1 = Page.create(:name => "top page")
22
+ p1.should_receive(:make_editable)
23
+ Page.should_receive(:find).with(:first, :lock => true,
24
+ :conditions => ["status_cd = ?", '00'], :order => "id asc").and_return(p1)
25
+ Page.process_state(:status_cd, :created)
26
+ #
27
+ Page.count.should == 1
28
+ Page.count(:conditions => "status_cd = '00'").should == 0
29
+ Page.count(:conditions => "status_cd = '01'").should == 1
30
+ end
31
+
32
+ it "valid with another record" do
33
+ p1 = Page.create(:name => "top page")
34
+ p2 = Page.create(:name => "about page")
35
+ p1.should_receive(:make_editable)
36
+ Page.should_receive(:find).with(:first, :lock => true,
37
+ :conditions => ["status_cd = ?", '00'], :order => "id asc").and_return(p1)
38
+ Page.process_state(:status_cd, :created)
39
+ #
40
+ Page.count.should == 2
41
+ Page.count(:conditions => "status_cd = '00'").should == 1
42
+ Page.count(:conditions => "status_cd = '01'").should == 1
43
+ end
44
+
45
+
46
+ it "validation error" do
47
+ p1 = Page.create(:name => "top page")
48
+ p1.should_receive(:make_editable)
49
+ p1.name = nil
50
+ Page.should_receive(:find).with(:first, :lock => true,
51
+ :conditions => ["status_cd = ?", '00'], :order => "id asc").and_return(p1)
52
+ lambda{
53
+ Page.process_state(:status_cd, :created)
54
+ }.should raise_error(ActiveRecord::RecordInvalid)
55
+
56
+ Page.count.should == 1
57
+ Page.count(:conditions => "status_cd = '00'").should == 1
58
+ Page.count(:conditions => "status_cd = '01'").should == 0
59
+ StateFlow::Log.count.should == 1
60
+ log = StateFlow::Log.first
61
+ log.target_type.should == 'Page'
62
+ log.target_id.should == p1.id
63
+ log.origin_state.should == '00'
64
+ log.origin_state_key.should == 'created'
65
+ log.dest_state.should == '01'
66
+ log.dest_state_key.should == 'editable'
67
+ log.level.should == 'error'
68
+ log.descriptions.should =~ /^Validation failed: Name can't be blank/
69
+ log.descriptions.should =~ /spec\/page_spec.rb/
70
+ end
71
+
72
+ end
73
+
74
+ describe ":editable => event(:apply) => :approving" do
75
+ it "valid" do
76
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:editable))
77
+ p1.apply
78
+ p1.reload
79
+ p1.status_key.should == :approving
80
+ StateFlow::Log.count.should == 0
81
+ end
82
+
83
+ it "validation error" do
84
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:editable))
85
+ p1.name = nil
86
+ lambda{
87
+ p1.apply
88
+ }.should raise_error(ActiveRecord::RecordInvalid)
89
+ p1.reload
90
+ p1.status_key.should == :editable
91
+ #
92
+ StateFlow::Log.count.should == 1
93
+ log = StateFlow::Log.first
94
+ log.target_type.should == 'Page'
95
+ log.target_id.should == p1.id
96
+ log.origin_state.should == '01'
97
+ log.origin_state_key.should == 'editable'
98
+ log.dest_state.should == '02'
99
+ log.dest_state_key.should == 'approving'
100
+ log.level.should == 'error'
101
+ log.descriptions.should =~ /^Validation failed: Name can't be blank/
102
+ log.descriptions.should =~ /spec\/page_spec.rb/
103
+ end
104
+
105
+ end
106
+
107
+ describe ":approving => event(:approve) => :approved" do
108
+ it "valid" do
109
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:approving))
110
+ p1.approve
111
+ p1.reload
112
+ p1.status_key.should == :approved
113
+ StateFlow::Log.count.should == 0
114
+ end
115
+
116
+ it "validation error" do
117
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:approving))
118
+ p1.name = nil
119
+ lambda{
120
+ p1.approve
121
+ }.should raise_error(ActiveRecord::RecordInvalid)
122
+ p1.reload
123
+ p1.status_key.should == :approving
124
+ #
125
+ StateFlow::Log.count.should == 1
126
+ log = StateFlow::Log.first
127
+ log.target_type.should == 'Page'
128
+ log.target_id.should == p1.id
129
+ log.origin_state.should == '02'
130
+ log.origin_state_key.should == 'approving'
131
+ log.dest_state.should == '03'
132
+ log.dest_state_key.should == 'approved'
133
+ log.level.should == 'error'
134
+ log.descriptions.should =~ /^Validation failed: Name can't be blank/
135
+ log.descriptions.should =~ /spec\/page_spec.rb/
136
+ end
137
+ end
138
+
139
+ describe ":approving => event(:reject) => :editable" do
140
+ it "valid" do
141
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:approving))
142
+ p1.reject
143
+ p1.reload
144
+ p1.status_key.should == :editable
145
+ StateFlow::Log.count.should == 0
146
+ end
147
+
148
+ it "validation error" do
149
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:approving))
150
+ p1.name = nil
151
+ lambda{
152
+ p1.reject
153
+ }.should raise_error(ActiveRecord::RecordInvalid)
154
+ p1.reload
155
+ p1.status_key.should == :approving
156
+ #
157
+ StateFlow::Log.count.should == 1
158
+ log = StateFlow::Log.first
159
+ log.target_type.should == 'Page'
160
+ log.target_id.should == p1.id
161
+ log.origin_state.should == '02'
162
+ log.origin_state_key.should == 'approving'
163
+ log.dest_state.should == '01'
164
+ log.dest_state_key.should == 'editable'
165
+ log.level.should == 'error'
166
+ log.descriptions.should =~ /^Validation failed: Name can't be blank/
167
+ log.descriptions.should =~ /spec\/page_spec.rb/
168
+ end
169
+ end
170
+
171
+ describe ":approved => event(:publish) => :waiting_publish" do
172
+ it "valid" do
173
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:approved))
174
+ p1.publish
175
+ p1.reload
176
+ p1.status_key.should == :waiting_publish
177
+ StateFlow::Log.count.should == 0
178
+ end
179
+
180
+ it "validation error" do
181
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:approved))
182
+ p1.name = nil
183
+ lambda{
184
+ p1.publish
185
+ }.should raise_error(ActiveRecord::RecordInvalid)
186
+ p1.reload
187
+ p1.status_key.should == :approved
188
+ #
189
+ StateFlow::Log.count.should == 1
190
+ log = StateFlow::Log.first
191
+ log.target_type.should == 'Page'
192
+ log.target_id.should == p1.id
193
+ log.origin_state.should == '03'
194
+ log.origin_state_key.should == 'approved'
195
+ log.dest_state.should == '04'
196
+ log.dest_state_key.should == 'waiting_publish'
197
+ log.level.should == 'error'
198
+ log.descriptions.should =~ /^Validation failed: Name can't be blank/
199
+ log.descriptions.should =~ /spec\/page_spec.rb/
200
+ end
201
+ end
202
+
203
+ describe ":waiting_publish => :publishing" do
204
+ it "valid" do
205
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:waiting_publish))
206
+ Page.process_state(:status_cd, :waiting_publish)
207
+ #
208
+ Page.count.should == 1
209
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:waiting_publish)]).should == 0
210
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publishing)]).should == 1
211
+ end
212
+
213
+ it "validation error" do
214
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:waiting_publish))
215
+ p1_backup = p1.clone
216
+ p1.name = nil
217
+ Page.should_receive(:find).with(:first, :lock => true,
218
+ :conditions => ["status_cd = ?", Page.status_id_by_key(:waiting_publish)], :order => "id asc").and_return(p1)
219
+ Page.should_receive(:find).with(p1.id).and_return(p1_backup)
220
+ lambda{
221
+ Page.process_state(:status_cd, :waiting_publish)
222
+ }.should raise_error(ActiveRecord::RecordInvalid)
223
+ Page.count.should == 1
224
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:waiting_publish)]).should == 0
225
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publishing)]).should == 0
226
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publish_failure)]).should == 1
227
+ StateFlow::Log.count.should == 1
228
+ log = StateFlow::Log.first
229
+ log.target_type.should == 'Page'
230
+ log.target_id.should == p1.id
231
+ log.origin_state.should == '04'
232
+ log.origin_state_key.should == 'waiting_publish'
233
+ log.dest_state.should == '05'
234
+ log.dest_state_key.should == 'publishing'
235
+ log.level.should == 'error'
236
+ log.descriptions.should =~ /^Validation failed: Name can't be blank/
237
+ log.descriptions.should =~ /spec\/page_spec.rb/
238
+ end
239
+
240
+ end
241
+
242
+
243
+ describe ":waiting_publish => :publishing" do
244
+ it "valid" do
245
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:waiting_publish))
246
+ Page.process_state(:status_cd, :waiting_publish)
247
+ #
248
+ Page.count.should == 1
249
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:waiting_publish)]).should == 0
250
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publishing)]).should == 1
251
+ end
252
+
253
+ it "validation error" do
254
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:waiting_publish))
255
+ p1_backup = p1.clone
256
+ p1.name = nil
257
+ Page.should_receive(:find).with(:first, :lock => true,
258
+ :conditions => ["status_cd = ?", Page.status_id_by_key(:waiting_publish)], :order => "id asc").and_return(p1)
259
+ # ステータス変更時のsave!で発生する例外による失敗によって対象となるレコードのキーを
260
+ # :failureで指定された:publish_failureに設定して保存するため、
261
+ # バリデーションエラーのないデータをid指定でfindするためここでモックを指定します。
262
+ Page.should_receive(:find).with(p1.id).and_return(p1_backup)
263
+ lambda{
264
+ Page.process_state(:status_cd, :waiting_publish)
265
+ }.should raise_error(ActiveRecord::RecordInvalid)
266
+ Page.count.should == 1
267
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:waiting_publish)]).should == 0
268
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publishing)]).should == 0
269
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publish_failure)]).should == 1
270
+ StateFlow::Log.count.should == 1
271
+ log = StateFlow::Log.first
272
+ log.target_type.should == 'Page'
273
+ log.target_id.should == p1.id
274
+ log.origin_state.should == '04'
275
+ log.origin_state_key.should == 'waiting_publish'
276
+ log.dest_state.should == '05'
277
+ log.dest_state_key.should == 'publishing'
278
+ log.level.should == 'error'
279
+ log.descriptions.should =~ /^Validation failed: Name can't be blank/
280
+ log.descriptions.should =~ /spec\/page_spec.rb/
281
+ end
282
+
283
+ end
284
+
285
+
286
+ describe ":publishing => action(:start_publish)" do
287
+ it "valid" do
288
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:publishing))
289
+ Page.process_state(:status_cd, :publishing)
290
+ # Page.process_stateによって:start_publishが実行されて、そのメソッド内部でステータスが変更されます。
291
+ Page.count.should == 1
292
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publishing)]).should == 0
293
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publishing_done)]).should == 1
294
+ end
295
+
296
+ it "validation error" do
297
+ Page.logger.debug("*" * 100)
298
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:publishing))
299
+ p1_backup = Page.find(p1.id)
300
+ p1.name = nil
301
+ p1.valid?.should == false
302
+ Page.should_receive(:find).with(:first,
303
+ :conditions => ["status_cd = ?", Page.status_id_by_key(:publishing)], :order => "id asc").and_return(p1)
304
+ Page.should_receive(:find).with(p1.id).and_return(p1_backup)
305
+
306
+ lambda{
307
+ Page.process_state(:status_cd, :publishing)
308
+ }.should raise_error(ActiveRecord::RecordInvalid)
309
+ Page.count.should == 1
310
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publishing)]).should == 0
311
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publishing_done)]).should == 0
312
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publish_failure)]).should == 1
313
+ StateFlow::Log.count.should == 1
314
+ log = StateFlow::Log.first
315
+ log.target_type.should == 'Page'
316
+ log.target_id.should == p1.id
317
+ log.origin_state.should == '05'
318
+ log.origin_state_key.should == 'publishing'
319
+ log.dest_state.should == nil # '06' # メソッド内で指定しているのでnil
320
+ log.dest_state_key.should == nil # 'publishing_done' # メソッド内で指定しているのでnil
321
+ log.level.should == 'error'
322
+ log.descriptions.should =~ /^Validation failed: Name can't be blank/
323
+ log.descriptions.should =~ /spec\/page_spec.rb/
324
+ end
325
+ end
326
+
327
+
328
+ describe ":publishing_done => :published, :if => :accessable?" do
329
+ it "valid" do
330
+ p1 = Page.create(:name => "published top page", :status_cd => Page.status_id_by_key(:publishing_done))
331
+ Page.process_state(:status_cd, :publishing_done)
332
+ # Page.process_stateによってaccessable?が実行されて、
333
+ # trueならステータス変更されます。このケースではtrueを返します。
334
+ Page.count.should == 1
335
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publishing_done)]).should == 0
336
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:published)]).should == 1
337
+ StateFlow::Log.count.should == 0
338
+ end
339
+
340
+ it "do nothing" do
341
+ p1 = Page.create(:name => "closed top page", :status_cd => Page.status_id_by_key(:publishing_done))
342
+ Page.process_state(:status_cd, :publishing_done)
343
+ # Page.process_stateによってaccessable?が実行されて、
344
+ # trueならステータス変更されます。このケースではfalseを返すので何も実行しません。
345
+ Page.count.should == 1
346
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publishing_done)]).should == 1
347
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:published)]).should == 0
348
+ StateFlow::Log.count.should == 0
349
+ end
350
+
351
+ it "validation error" do
352
+ Page.logger.debug("*" * 100)
353
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:publishing))
354
+ p1_backup = Page.find(p1.id)
355
+ p1.name = nil
356
+ p1.valid?.should == false
357
+ Page.should_receive(:find).with(:first,
358
+ :conditions => ["status_cd = ?", Page.status_id_by_key(:publishing)], :order => "id asc").and_return(p1)
359
+ Page.should_receive(:find).with(p1.id).and_return(p1_backup)
360
+
361
+ lambda{
362
+ Page.process_state(:status_cd, :publishing)
363
+ }.should raise_error(ActiveRecord::RecordInvalid)
364
+ Page.count.should == 1
365
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publishing)]).should == 0
366
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publishing_done)]).should == 0
367
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:publish_failure)]).should == 1
368
+ StateFlow::Log.count.should == 1
369
+ log = StateFlow::Log.first
370
+ log.target_type.should == 'Page'
371
+ log.target_id.should == p1.id
372
+ log.origin_state.should == '05'
373
+ log.origin_state_key.should == 'publishing'
374
+ log.dest_state.should == nil # '06' # メソッド内で指定しているのでnil
375
+ log.dest_state_key.should == nil # 'publishing_done' # メソッド内で指定しているのでnil
376
+ log.level.should == 'error'
377
+ log.descriptions.should =~ /^Validation failed: Name can't be blank/
378
+ log.descriptions.should =~ /spec\/page_spec.rb/
379
+ end
380
+ end
381
+
382
+
383
+ describe ":published => {event(:close) => :waiting_closing}" do
384
+ it "valid" do
385
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:published))
386
+ p1.close
387
+ p1.reload
388
+ p1.status_key.should == :waiting_closing
389
+ StateFlow::Log.count.should == 0
390
+ end
391
+
392
+ it "validation error" do
393
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:published))
394
+ p1.name = nil
395
+ lambda{
396
+ p1.close
397
+ }.should raise_error(ActiveRecord::RecordInvalid)
398
+ p1.reload
399
+ p1.status_key.should == :published
400
+ #
401
+ StateFlow::Log.count.should == 1
402
+ log = StateFlow::Log.first
403
+ log.target_type.should == 'Page'
404
+ log.target_id.should == p1.id
405
+ log.origin_state.should == '07'
406
+ log.origin_state_key.should == 'published'
407
+ log.dest_state.should == '09'
408
+ log.dest_state_key.should == 'waiting_closing'
409
+ log.level.should == 'error'
410
+ log.descriptions.should =~ /^Validation failed: Name can't be blank/
411
+ log.descriptions.should =~ /spec\/page_spec.rb/
412
+ end
413
+ end
414
+
415
+
416
+
417
+ describe ":waiting_closing => :closing, :lock => true" do
418
+ it "valid" do
419
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:waiting_closing))
420
+ Page.should_receive(:find).with(:first, :lock => true,
421
+ :conditions => ["status_cd = ?", '09'], :order => "id asc").and_return(p1)
422
+ Page.process_state(:status_cd, :waiting_closing)
423
+ #
424
+ Page.count.should == 1
425
+ Page.count(:conditions => "status_cd = '09'").should == 0
426
+ Page.count(:conditions => "status_cd = '10'").should == 1
427
+ end
428
+
429
+ it "validation error" do
430
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:waiting_closing))
431
+ p1_backup = Page.find(p1.id)
432
+ p1.name = nil
433
+ Page.should_receive(:find).with(:first, :lock => true,
434
+ :conditions => ["status_cd = ?", '09'], :order => "id asc").and_return(p1)
435
+ Page.should_receive(:find).with(p1.id).and_return(p1_backup)
436
+ lambda{
437
+ Page.process_state(:status_cd, :waiting_closing)
438
+ }.should raise_error(ActiveRecord::RecordInvalid)
439
+
440
+ Page.count.should == 1
441
+ Page.count(:conditions => "status_cd = '09'").should == 0
442
+ Page.count(:conditions => "status_cd = '10'").should == 0
443
+ Page.count(:conditions => "status_cd = '13'").should == 1
444
+ StateFlow::Log.count.should == 1
445
+ log = StateFlow::Log.first
446
+ log.target_type.should == 'Page'
447
+ log.target_id.should == p1.id
448
+ log.origin_state.should == '09'
449
+ log.origin_state_key.should == 'waiting_closing'
450
+ log.dest_state.should == '10'
451
+ log.dest_state_key.should == 'closing'
452
+ log.level.should == 'error'
453
+ log.descriptions.should =~ /^Validation failed: Name can't be blank/
454
+ log.descriptions.should =~ /spec\/page_spec.rb/
455
+ end
456
+
457
+ end
458
+
459
+
460
+
461
+ describe ":closing => {action(:start_closing) => :closing_done}" do
462
+ it "valid" do
463
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:closing))
464
+ Page.process_state(:status_cd, :closing)
465
+ Page.count.should == 1
466
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:closing)]).should == 0
467
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:closing_done)]).should == 1
468
+ end
469
+
470
+ it "validation error" do
471
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:closing))
472
+ p1_backup = Page.find(p1.id)
473
+ p1.name = nil
474
+ p1.valid?.should == false
475
+ Page.should_receive(:find).with(:first,
476
+ :conditions => ["status_cd = ?", Page.status_id_by_key(:closing)], :order => "id asc").and_return(p1)
477
+ Page.should_receive(:find).with(p1.id).and_return(p1_backup)
478
+
479
+ lambda{
480
+ Page.process_state(:status_cd, :closing)
481
+ }.should raise_error(ActiveRecord::RecordInvalid)
482
+ Page.count.should == 1
483
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:closing)]).should == 0
484
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:closing_done)]).should == 0
485
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:closing_failure)]).should == 1
486
+ StateFlow::Log.count.should == 1
487
+ log = StateFlow::Log.first
488
+ log.target_type.should == 'Page'
489
+ log.target_id.should == p1.id
490
+ log.origin_state.should == '10'
491
+ log.origin_state_key.should == 'closing'
492
+ log.dest_state.should == "11"
493
+ log.dest_state_key.should == 'closing_done'
494
+ log.level.should == 'error'
495
+ log.descriptions.should =~ /^Validation failed: Name can't be blank/
496
+ log.descriptions.should =~ /spec\/page_spec.rb/
497
+ end
498
+ end
499
+
500
+
501
+ describe ":closing_done => :closed, :unless => :accessable?" do
502
+ it "valid" do
503
+ p1 = Page.create(:name => "closed top page", :status_cd => Page.status_id_by_key(:closing_done))
504
+ Page.process_state(:status_cd, :closing_done)
505
+ # Page.process_stateによってaccessable?が実行されて、
506
+ # trueならステータス変更されます。このケースではtrueを返します。
507
+ Page.count.should == 1
508
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:closing_done)]).should == 0
509
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:closed)]).should == 1
510
+ StateFlow::Log.count.should == 0
511
+ end
512
+
513
+ it "do nothing" do
514
+ p1 = Page.create(:name => "still published top page", :status_cd => Page.status_id_by_key(:closing_done))
515
+ Page.process_state(:status_cd, :closing_done)
516
+ # Page.process_stateによってaccessable?が実行されて、
517
+ # trueならステータス変更されます。このケースではfalseを返すので何も実行しません。
518
+ Page.count.should == 1
519
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:closing_done)]).should == 1
520
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:closed)]).should == 0
521
+ StateFlow::Log.count.should == 0
522
+ end
523
+
524
+ it "validation error" do
525
+ Page.logger.debug("*" * 100)
526
+ p1 = Page.create(:name => "top page", :status_cd => Page.status_id_by_key(:closing))
527
+ p1_backup = Page.find(p1.id)
528
+ p1.name = nil
529
+ p1.valid?.should == false
530
+ Page.should_receive(:find).with(:first,
531
+ :conditions => ["status_cd = ?", Page.status_id_by_key(:closing)], :order => "id asc").and_return(p1)
532
+ Page.should_receive(:find).with(p1.id).and_return(p1_backup)
533
+
534
+ lambda{
535
+ Page.process_state(:status_cd, :closing)
536
+ }.should raise_error(ActiveRecord::RecordInvalid)
537
+ Page.count.should == 1
538
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:closing_done)]).should == 0
539
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:closed)]).should == 0
540
+ Page.count(:conditions => ["status_cd = ?", Page.status_id_by_key(:closing_failure)]).should == 1
541
+ StateFlow::Log.count.should == 1
542
+ log = StateFlow::Log.first
543
+ log.target_type.should == 'Page'
544
+ log.target_id.should == p1.id
545
+ log.origin_state.should == '10'
546
+ log.origin_state_key.should == 'closing'
547
+ log.dest_state.should == '11'
548
+ log.dest_state_key.should == 'closing_done'
549
+ log.level.should == 'error'
550
+ log.descriptions.should =~ /^Validation failed: Name can't be blank/
551
+ log.descriptions.should =~ /spec\/page_spec.rb/
552
+ end
553
+ end
554
+ end
@@ -0,0 +1,70 @@
1
+ # -*- coding: utf-8 -*-
2
+ class Page < ActiveRecord::Base
3
+ validates_presence_of :name
4
+
5
+ selectable_attr :status_cd do
6
+ entry '00', :created , '生成済'
7
+ entry '01', :editable , '編集可'
8
+ entry '02', :approving , '承認中'
9
+ entry '03', :approved , '承認済'
10
+ entry '04', :waiting_publish, '公開待ち'
11
+ entry '05', :publishing , '公開処理中'
12
+ entry '06', :publishing_done, '公開処理完了'
13
+ entry '07', :published , '公開済'
14
+ entry '08', :publish_failure, '公開失敗'
15
+ entry '09', :waiting_closing, '終了待ち'
16
+ entry '10', :closing , '終了処理中'
17
+ entry '11', :closing_done , '終了処理完了'
18
+ entry '12', :closed , '終了済'
19
+ entry '13', :closing_failure, '終了失敗'
20
+ end
21
+
22
+ state_flow(:status_cd) do
23
+ state :created => {action(:make_editable) => :editable, :lock => true}
24
+ state :editable => {event(:apply) => :approving}
25
+ state :approving => {
26
+ event(:approve) => :approved,
27
+ event(:reject) => :editable
28
+ }
29
+ state :approved => {event(:publish) => :waiting_publish}
30
+
31
+ with_options(:failure => :publish_failure) do |publishing|
32
+ publishing.state :waiting_publish => :publishing, :lock => true
33
+ # 下記のように状態を遷移させたい場合でもメソッド中にそれを記述させたい場合、
34
+ # publishing.state :publishing => {action(:start_publish) => :publishing_done}
35
+ # 以下のように遷移先のメソッドを省略して、メソッド中に記述することが可能です。
36
+ publishing.state :publishing => action(:start_publish)
37
+ publishing.state :publishing_done => :published, :if => :accessable?
38
+ publishing.state :publish_failure
39
+ end
40
+
41
+ state :published => {event(:close) => :waiting_closing}
42
+
43
+ with_options(:failure => :closing_failure) do |closing|
44
+ closing.state :waiting_closing => :closing, :lock => true
45
+ closing.state :closing => {action(:start_closing) => :closing_done}
46
+ closing.state :closing_done => :closed, :unless => :accessable?
47
+ closing.state :closing_failure
48
+ end
49
+
50
+ state :closed
51
+ end
52
+
53
+ def make_editable
54
+ end
55
+
56
+ def start_publish
57
+ self.status_key = :publishing_done
58
+ save!
59
+ end
60
+
61
+ def start_closing
62
+ end
63
+
64
+ def accessable?
65
+ # 本来なら実際のページにアクセスしてみてオッケーかどうかを確認するような処理を書きます。
66
+ name =~ /published/
67
+ end
68
+
69
+
70
+ end
data/spec/schema.rb ADDED
@@ -0,0 +1,24 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ # Users are created and updated by other Users
3
+ create_table :pages, :force => true do |t|
4
+ t.column :name, :string
5
+ t.column :status_cd , :string, :limit => 2, :null => false, :default => '00'
6
+ t.column :created_on, :datetime
7
+ t.column :updated_at, :datetime
8
+ end
9
+
10
+ create_table :state_flow_logs, :force => true do |t|
11
+ t.string :target_type
12
+ t.integer :target_id
13
+ t.string :origin_state
14
+ t.string :origin_state_key
15
+ t.string :dest_state
16
+ t.string :dest_state_key
17
+ t.string :level, :limit => 5, :null => false, :default => 'debug'
18
+ t.text :descriptions
19
+ t.datetime :created_on
20
+ t.datetime :updated_at
21
+ end
22
+
23
+
24
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,6 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ --loadby
5
+ mtime
6
+ --reverse