OSDN Git Service

t#29400:itr3?
[pettanr/pettanr.git] / spec / models / story_spec.rb
1 # -*- encoding: utf-8 -*-
2 require 'spec_helper'
3 #ストーリー
4 describe Story do
5   before do
6     FactoryGirl.create :admin
7     @sp = FactoryGirl.create :system_picture
8     @lg = FactoryGirl.create :license_group
9     @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
10     @user = FactoryGirl.create( :user_yas)
11     @author = @user.author
12     @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
13     @other_user = FactoryGirl.create( :user_yas)
14     @other_author = @other_user.author
15   end
16   
17   describe '検証に於いて' do
18     before do
19       @comic = FactoryGirl.create :comic, :author_id => @author.id
20       @panel = FactoryGirl.create :panel, :author_id => @author.id
21       @story = FactoryGirl.build :story, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
22     end
23     
24     context 'オーソドックスなデータのとき' do
25       it '下限データが通る' do
26         @story.t = 0
27         @story.should be_valid
28       end
29       it '上限データが通る' do
30         @story.t = 99999
31         @story.should be_valid
32       end
33     end
34     
35     context 'comic_idを検証するとき' do
36       it 'nullなら失敗する' do
37         @story.comic_id = nil
38         @story.should_not be_valid
39       end
40       it '数値でなければ失敗する' do
41         @story.comic_id = 'a'
42         @story.should_not be_valid
43       end
44       it '存在するコミックでなければ失敗する' do
45         @story.comic_id = 0
46         @story.should_not be_valid
47       end
48     end
49     
50     context 'panel_idを検証するとき' do
51       it 'nullなら失敗する' do
52         @story.panel_id = nil
53         @story.should_not be_valid
54       end
55       it '数値でなければ失敗する' do
56         @story.panel_id = 'a'
57         @story.should_not be_valid
58       end
59       it '存在するコマでなければ失敗する' do
60         @story.panel_id = 0
61         @story.should_not be_valid
62       end
63     end
64     
65     context 'tを検証するとき' do
66       it 'nullなら失敗する' do
67         @story.t = nil
68         @story.should_not be_valid
69       end
70       it '数値でなければ失敗する' do
71         @story.t = 'a'
72         @story.should_not be_valid
73       end
74       it '負なら失敗する' do
75         @story.t = -1
76         @story.should_not be_valid
77       end
78     end
79     
80     context 'author_idを検証するとき' do
81       it 'nullなら失敗する' do
82         @story.author_id = nil
83         @story.should_not be_valid
84       end
85       it '数値でなければ失敗する' do
86         @story.author_id = 'a'
87         @story.should_not be_valid
88       end
89       it '存在する作家でなければ失敗する' do
90         @story.author_id = 0
91         @story.should_not be_valid
92       end
93     end
94     context '全体を検証するとき' do
95     end
96   end
97   
98   describe 'デフォルト値補充に於いて' do
99     before do
100       @comic = FactoryGirl.create :comic, :author_id => @author.id
101       @panel = FactoryGirl.create :panel, :author_id => @author.id
102     end
103     
104     #dbのデフォルト値が0だから明示的にnilにしないと追加ができない
105     it 'tをnilにする' do
106       @story = FactoryGirl.build :story, :comic_id => @comic.id, :panel_id => @panel.id
107       @story.supply_default
108       @story.t.should be_nil
109     end
110     
111   end
112   
113   describe '上書き補充に於いて' do
114     before do
115       @comic = FactoryGirl.create :comic, :author_id => @author.id
116       @panel = FactoryGirl.create :panel, :author_id => @author.id
117     end
118     
119     context 'author_idを補充' do
120       it '問答無用でauthor_idを補充する' do
121         @story = FactoryGirl.build :story, :comic_id => @comic.id, :panel_id => @panel.id
122         @story.author_id = nil
123         @story.overwrite @author
124         @story.author_id.should eq @author.id
125       end
126     end
127     
128   end
129   
130   describe '所持判定に於いて' do
131     before do
132       @comic = FactoryGirl.create :comic, :author_id => @author.id
133       @panel = FactoryGirl.create :panel, :author_id => @author.id
134       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
135       @comico = FactoryGirl.create :comic, :author_id => @other_author.id
136       @panelo = FactoryGirl.create :panel, :author_id => @other_author.id
137       @storyo = FactoryGirl.create :story, :author_id => @other_author.id, :comic_id => @comico.id, :panel_id => @panelo.id
138     end
139     it '自分のストーリーならyes' do
140       @story.own?(@author).should == true
141     end
142     it '他人のストーリーならno' do
143       @storyo.own?(@author).should == false
144     end
145   end
146   describe '一覧取得に於いて' do
147     before do
148       @comic = FactoryGirl.create :comic, :author_id => @author.id
149       @panel = FactoryGirl.create :panel, :author_id => @author.id
150       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
151       @panel2 = FactoryGirl.create :panel, :author_id => @author.id, :publish => 0
152       @other_comic = FactoryGirl.create :comic, :author_id => @other_author.id, :visible => 1
153       @other_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1
154     end
155     context 'offset補正について' do
156       it '文字列から数値に変換される' do
157         Story.offset(100, '8').should eq 8
158       end
159       it 'nilの場合は0になる' do
160         Story.offset(100).should eq 0
161       end
162       #投稿されたコマ数以上の値が指定されたときは、最後のコマだけになる
163       #最後のコマとは、コマ数‐1.
164       it '1件のときオフセット1なら0になる' do
165         Story.offset(1, '1').should eq 0
166       end
167       it '5件のときオフセット5なら4になる' do
168         Story.offset(5, '5').should eq 4
169       end
170       # 負の値が指定されたときは、最後のコマから数えてコマを飛ばして表示する。
171       #-4のときは、最後から4つのコマを表示する。 
172       it '2件のときオフセット-1なら1になる' do
173         Story.offset(2, '-1').should eq 1
174       end
175       it '5件のときオフセット-2なら3になる' do
176         Story.offset(5, '-2').should eq 3
177       end
178       # 最終的なが負になるなど、不正な値が入ったときは0となる。 
179       it '2件のときオフセット-5なら0になる' do
180         Story.offset(2, '-5').should eq 0
181       end
182     end
183     context 'panel_count補正について' do
184       it '文字列から数値に変換される' do
185         Story.panel_count(100, '7').should eq 7
186       end
187       it 'nilの場合はStory.default_panel_sizeになる' do
188         Story.panel_count(100).should eq Story.default_panel_size
189       end
190       it '0以下の場合はStory.default_panel_sizeになる' do
191         Story.panel_count(100, '0').should eq Story.default_panel_size
192       end
193       it 'Story.max_panel_sizeを超えた場合はStory.max_panel_sizeになる' do
194         Story.panel_count(100, '1000').should eq Story.max_panel_size
195       end
196     end
197     it 'リストを返す' do
198       c = Story.list @comic, @author
199       c.should eq [@story]
200     end
201     it 't順で並んでいる' do
202       #公開コミックの公開コマは(他人のコミックであっても)含んでいる
203       v = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 1
204       c = Story.list @comic, @author
205       c.should eq [ @story, v]
206     end
207     it '非公開のコマは含まない' do
208       h = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel2.id, :t => 1
209       c = Story.list @comic, @author
210       c.should eq [ @story]
211     end
212     context 'DBに5件あって1ページの件数を2件に変えたとして' do
213       before do
214         @story2 = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 1
215         @story3 = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 2
216         @story4 = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 3
217         @story5 = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 4
218       end
219       it 'offset=0なら末尾2件を返す' do
220         #時系列で並んでいる
221         c = Story.list( @comic, @author, 0, 2)
222         c.should eq [@story, @story2]
223       end
224       it 'offset=2なら中間2件を返す' do
225         c = Story.list(@comic, @author, 2, 2)
226         c.should eq [@story3, @story4]
227       end
228       it 'offset=4なら先頭1件を返す' do
229         c = Story.list(@comic, @author, 4, 2)
230         c.should eq [@story5]
231       end
232     end
233   end
234   describe 'list関連テーブルプションに於いて' do
235     it 'includeキーを含んでいる' do
236       r = Story.list_opt
237       r.has_key?(:include).should be_true
238     end
239     it '3つの項目を含んでいる' do
240       r = Story.list_opt[:include]
241       r.should have(3).items
242     end
243     it 'コミックを含んでいる' do
244       r = Story.list_opt[:include]
245       r.has_key?(:comic).should be_true
246     end
247       it 'コミックは作家を含んでいる' do
248         r = Story.list_opt[:include]
249         r[:comic].has_key?(:author).should be_true
250       end
251     it '作家を含んでいる' do
252       r = Story.list_opt[:include]
253       r.has_key?(:author).should be_true
254     end
255     it 'コマを含んでいる' do
256       r = Story.list_opt[:include]
257       r.has_key?(:panel).should be_true
258     end
259       it 'コマは作家を含んでいる' do
260         r = Story.list_opt[:include]
261         r[:panel].has_key?(:author).should be_true
262       end
263       it 'コマはコマ絵を含んでいる' do
264         r = Story.list_opt[:include]
265         r[:panel].has_key?(:panel_pictures).should be_true
266       end
267         it 'コマ絵は実素材を含んでいる' do
268           r = Story.list_opt[:include]
269           r[:panel][:panel_pictures].has_key?(:picture).should be_true
270         end
271           it '実素材は絵師を含んでいる' do
272             r = Story.list_opt[:include]
273             r[:panel][:panel_pictures][:picture].has_key?(:artist).should be_true
274           end
275           it '実素材はライセンスを含んでいる' do
276             r = Story.list_opt[:include]
277             r[:panel][:panel_pictures][:picture].has_key?(:license).should be_true
278           end
279       it 'コマはフキダシを含んでいる' do
280         r = Story.list_opt[:include]
281         r[:panel].has_key?(:speech_balloons).should be_true
282       end
283         it 'フキダシはフキダシ枠を含んでいる' do
284           r = Story.list_opt[:include]
285           r[:panel][:speech_balloons].has_key?(:balloons).should be_true
286         end
287         it 'フキダシはセリフを含んでいる' do
288           r = Story.list_opt[:include]
289           r[:panel][:speech_balloons].has_key?(:speeches).should be_true
290         end
291   end
292   describe 'json一覧出力オプションに於いて' do
293     it 'includeキーを含んでいる' do
294       r = Story.list_json_opt
295       r.has_key?(:include).should be_true
296     end
297     it '3つの項目を含んでいる' do
298       r = Story.list_json_opt[:include]
299       r.should have(3).items
300     end
301     it 'コミックを含んでいる' do
302       r = Story.list_json_opt[:include]
303       r.has_key?(:comic).should be_true
304     end
305       it 'コミックは作家を含んでいる' do
306         r = Story.list_json_opt[:include]
307         r[:comic].has_key?(:author).should be_true
308       end
309     it '作家を含んでいる' do
310       r = Story.list_json_opt[:include]
311       r.has_key?(:author).should be_true
312     end
313     it 'コマを含んでいる' do
314       r = Story.list_json_opt[:include]
315       r.has_key?(:panel).should be_true
316     end
317       it 'コマは作家を含んでいる' do
318         r = Story.list_json_opt[:include]
319         r[:panel].has_key?(:author).should be_true
320       end
321       it 'コマはコマ絵を含んでいる' do
322         r = Story.list_json_opt[:include]
323         r[:panel].has_key?(:panel_pictures).should be_true
324       end
325         it 'コマ絵は実素材を含んでいる' do
326           r = Story.list_json_opt[:include]
327           r[:panel][:panel_pictures].has_key?(:picture).should be_true
328         end
329           it '実素材は絵師を含んでいる' do
330             r = Story.list_json_opt[:include]
331             r[:panel][:panel_pictures][:picture].has_key?(:artist).should be_true
332           end
333           it '実素材はライセンスを含んでいる' do
334             r = Story.list_json_opt[:include]
335             r[:panel][:panel_pictures][:picture].has_key?(:license).should be_true
336           end
337       it 'コマはフキダシを含んでいる' do
338         r = Story.list_json_opt[:include]
339         r[:panel].has_key?(:speech_balloons).should be_true
340       end
341         it 'フキダシはフキダシ枠を含んでいる' do
342           r = Story.list_json_opt[:include]
343           r[:panel][:speech_balloons].has_key?(:balloons).should be_true
344         end
345         it 'フキダシはセリフを含んでいる' do
346           r = Story.list_json_opt[:include]
347           r[:panel][:speech_balloons].has_key?(:speeches).should be_true
348         end
349   end
350   
351   describe '自分のストーリー一覧取得に於いて' do
352     before do
353       @comic = FactoryGirl.create :comic, :author_id => @author.id, :visible => 0
354       @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 0
355       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
356       @other_comic = FactoryGirl.create :comic, :author_id => @other_author.id, :visible => 1
357       @other_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1
358     end
359     context 'つつがなく終わるとき' do\r
360       it '一覧取得オプションを利用している' do\r
361         Story.stub(:list_opt).with(any_args).and_return({})\r
362         Story.should_receive(:list_opt).with(any_args).exactly(1)\r
363         r = Story.mylist @author
364       end\r
365     end\r
366     it 'リストを返す' do
367       s = Story.mylist @author
368       s.should eq [@story]
369     end
370     it '時系列で並んでいる' do
371       ns = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 1, :updated_at => Time.now + 100
372       sl = Story.mylist @author
373       sl.should eq [ns, @story]
374     end
375     it '他人のストーリーはコマコミックともに公開でも含まない' do
376       so = FactoryGirl.create :story, :author_id => @other_author.id, :comic_id => @other_comic.id, :panel_id => @other_panel.id
377       sl = Story.mylist @author
378       sl.should eq [@story]
379     end
380     it '自分のストーリーはコマコミックともには非公開でも含んでいる' do
381       nc = FactoryGirl.create :comic, :author_id => @author.id, :visible => 0, :updated_at => Time.now + 100
382       cl = Comic.mylist @author
383       cl.should eq [nc, @story]
384     end
385     context 'DBに5件あって1ページの件数を2件に変えたとして' do
386       before do
387         @story2 = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 1, :updated_at => Time.now + 100
388         @story3 = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 2, :updated_at => Time.now + 200
389         @story4 = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 3, :updated_at => Time.now + 300
390         @story5 = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 4, :updated_at => Time.now + 400
391       end
392       it '通常は2件を返す' do
393         c = Story.mylist @author, 1, 2
394         c.should have(2).items 
395       end
396       it 'page=1なら末尾2件を返す' do
397         #時系列で並んでいる
398         c = Story.mylist(@author, 1, 2)
399         c.should eq [@story5, @story4]
400       end
401       it 'page=2なら中間2件を返す' do
402         c = Story.mylist(@author, 2, 2)
403         c.should eq [@story3, @story2]
404       end
405       it 'page=3なら先頭1件を返す' do
406         c = Story.mylist(@author, 3, 2)
407         c.should eq [@story]
408       end
409     end
410     context 'DBに5件あって1ページの件数を0件に変えたとして' do
411       before do
412         @story2 = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 1, :updated_at => Time.now + 100
413         @story3 = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 2, :updated_at => Time.now + 200
414         @story4 = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 3, :updated_at => Time.now + 300
415         @story5 = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 4, :updated_at => Time.now + 400
416       end
417       it '通常は全件(5件)を返す' do
418         r = Story.mylist @author, 5, 0
419         r.should have(5).items 
420       end
421     end
422   end
423   
424   describe '編集取得に於いて' do
425     before do
426       @comic = FactoryGirl.create :comic, :author_id => @author.id
427       @panel = FactoryGirl.create :panel, :author_id => @author.id
428       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
429     end
430     context 'つつがなく終わるとき' do\r
431       it '単体取得オプションを利用している' do\r
432         Story.stub(:show_opt).with(any_args).and_return({})\r
433         Story.should_receive(:show_opt).with(any_args).exactly(1)\r
434         r = Story.edit @story.id, @author
435       end\r
436       it '所持判定を問い合わせている' do\r
437         Story.any_instance.stub(:own?).with(any_args).and_return(true)\r
438         Story.any_instance.should_receive(:own?).with(any_args).exactly(1)\r
439         r = Story.edit @story.id, @author
440       end\r
441     end\r
442     it '指定のストーリーを返す' do
443       l = Story.edit @story.id, @author
444       l.should eq @story
445     end
446     context '他人のストーリーを開こうとしたとき' do
447       it '403Forbidden例外を返す' do
448         Story.any_instance.stub(:own?).and_return(false)
449         lambda{
450           Story.edit @story.id, @author
451         }.should raise_error(ActiveRecord::Forbidden)
452       end
453     end
454     context '存在しないストーリーを開こうとしたとき' do
455       it '404RecordNotFound例外を返す' do
456         lambda{
457           Story.edit 110, @author
458         }.should raise_error(ActiveRecord::RecordNotFound)
459       end
460     end
461   end
462   
463   describe '単体取得オプションに於いて' do
464     it 'includeキーを含んでいる' do
465       r = Story.show_opt
466       r.has_key?(:include).should be_true
467     end
468     it '3つの項目を含んでいる' do
469       r = Story.show_opt[:include]
470       r.should have(3).items
471     end
472     it 'コミックを含んでいる' do
473       r = Story.show_opt[:include]
474       r.has_key?(:comic).should be_true
475     end
476       it 'コミックは作家を含んでいる' do
477         r = Story.show_opt[:include]
478         r[:comic].has_key?(:author).should be_true
479       end
480     it '作家を含んでいる' do
481       r = Story.show_opt[:include]
482       r.has_key?(:author).should be_true
483     end
484     it 'コマを含んでいる' do
485       r = Story.show_opt[:include]
486       r.has_key?(:panel).should be_true
487     end
488       it 'コマは作家を含んでいる' do
489         r = Story.show_opt[:include]
490         r[:panel].has_key?(:author).should be_true
491       end
492       it 'コマはコマ絵を含んでいる' do
493         r = Story.show_opt[:include]
494         r[:panel].has_key?(:panel_pictures).should be_true
495       end
496         it 'コマ絵は実素材を含んでいる' do
497           r = Story.show_opt[:include]
498           r[:panel][:panel_pictures].has_key?(:picture).should be_true
499         end
500           it '実素材は絵師を含んでいる' do
501             r = Story.show_opt[:include]
502             r[:panel][:panel_pictures][:picture].has_key?(:artist).should be_true
503           end
504           it '実素材はライセンスを含んでいる' do
505             r = Story.show_opt[:include]
506             r[:panel][:panel_pictures][:picture].has_key?(:license).should be_true
507           end
508       it 'コマはフキダシを含んでいる' do
509         r = Story.show_opt[:include]
510         r[:panel].has_key?(:speech_balloons).should be_true
511       end
512         it 'フキダシはフキダシ枠を含んでいる' do
513           r = Story.show_opt[:include]
514           r[:panel][:speech_balloons].has_key?(:balloons).should be_true
515         end
516         it 'フキダシはセリフを含んでいる' do
517           r = Story.show_opt[:include]
518           r[:panel][:speech_balloons].has_key?(:speeches).should be_true
519         end
520   end
521   describe 'json単体取得オプションに於いて' do
522     it 'includeキーを含んでいる' do
523       r = Story.show_json_opt
524       r.has_key?(:include).should be_true
525     end
526     it '3つの項目を含んでいる' do
527       r = Story.show_json_opt[:include]
528       r.should have(3).items
529     end
530     it 'コミックを含んでいる' do
531       r = Story.show_json_opt[:include]
532       r.has_key?(:comic).should be_true
533     end
534       it 'コミックは作家を含んでいる' do
535         r = Story.show_json_opt[:include]
536         r[:comic].has_key?(:author).should be_true
537       end
538     it '作家を含んでいる' do
539       r = Story.show_json_opt[:include]
540       r.has_key?(:author).should be_true
541     end
542     it 'コマを含んでいる' do
543       r = Story.show_json_opt[:include]
544       r.has_key?(:panel).should be_true
545     end
546       it 'コマは作家を含んでいる' do
547         r = Story.show_json_opt[:include]
548         r[:panel].has_key?(:author).should be_true
549       end
550       it 'コマはコマ絵を含んでいる' do
551         r = Story.show_json_opt[:include]
552         r[:panel].has_key?(:panel_pictures).should be_true
553       end
554         it 'コマ絵は実素材を含んでいる' do
555           r = Story.show_json_opt[:include]
556           r[:panel][:panel_pictures].has_key?(:picture).should be_true
557         end
558           it '実素材は絵師を含んでいる' do
559             r = Story.show_json_opt[:include]
560             r[:panel][:panel_pictures][:picture].has_key?(:artist).should be_true
561           end
562           it '実素材はライセンスを含んでいる' do
563             r = Story.show_json_opt[:include]
564             r[:panel][:panel_pictures][:picture].has_key?(:license).should be_true
565           end
566       it 'コマはフキダシを含んでいる' do
567         r = Story.show_json_opt[:include]
568         r[:panel].has_key?(:speech_balloons).should be_true
569       end
570         it 'フキダシはフキダシ枠を含んでいる' do
571           r = Story.show_json_opt[:include]
572           r[:panel][:speech_balloons].has_key?(:balloons).should be_true
573         end
574         it 'フキダシはセリフを含んでいる' do
575           r = Story.show_json_opt[:include]
576           r[:panel][:speech_balloons].has_key?(:speeches).should be_true
577         end
578   end
579   
580   describe 't補充値に於いて' do
581     before do
582       @comic = FactoryGirl.create :comic, :author_id => @author.id
583       @panel = FactoryGirl.create :panel, :author_id => @author.id
584     end
585     
586     context 'コミック初のコマなら' do
587       it '0を補充値とする' do
588         @story = FactoryGirl.build :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
589         @story.t = nil
590         r = Story.new_t @story.comic_id
591         r.should eq 0
592       end
593     end
594     context 'コミックに一個コマがあるとき' do
595       it '1を補充値とする' do
596         FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 0
597         @story = FactoryGirl.build :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
598         @story.t = nil
599         r = Story.new_t @story.comic_id
600         r.should eq 1
601       end
602     end
603     context 'コミックに2個コマがあるとき' do
604       it '2を補充値とする' do
605         FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 0
606         FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 1
607         @story = FactoryGirl.build :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
608         @story.t = nil
609         r = Story.new_t @story.comic_id
610         r.should eq 2
611       end
612     end
613   end
614   describe 'シリアライズチェックに於いて' do
615     context 'つつがなく終わるとき' do
616       it '0からシリアライズされているならTrueを返す' do
617         r = Story.serial? [0, 1, 2]
618         r.should be_true
619       end
620       it '見た目はシリアライズされてなくてもソート結果が無事ならtrueを返す' do
621         r = Story.serial? [0, 2, 1]
622         r.should be_true
623       end
624       it '見た目はシリアライズされてなくてもソート結果が無事ならtrueを返す' do
625         r = Story.serial? [ 2, 1, 4, 3, 0]
626         r.should be_true
627       end
628     end
629     context '異常なとき' do
630       it '0から始まらないならFalseを返す' do
631         r = Story.serial? [1, 2, 3]
632         r.should be_false
633       end
634       it '連続していないならFalseを返す' do
635         r = Story.serial? [0, 1, 2, 4]
636         r.should be_false
637       end
638       it '連続していないならFalseを返す' do
639         r = Story.serial? [0, 1, 2, 4, 5]
640         r.should be_false
641       end
642     end
643   end
644   describe 't収集に於いて' do
645     before do
646       @comic = FactoryGirl.create :comic, :author_id => @author.id
647       @panel = FactoryGirl.create :panel, :author_id => @author.id
648       @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
649       @comic2 = FactoryGirl.create :comic, :author_id => @author.id
650       @c2story = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
651     end
652     context 'つつがなく終わるとき' do
653       it 'ストーリーから同一コミックのtだけを収集している' do
654         r = Story.collect_t @story
655         r.should eq [0]
656       end
657     end
658     context '複数コマのとき' do
659       it 'ストーリーから同一コミックのtだけを収集している' do
660         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
661         r = Story.collect_t @story
662         r.sort.should eq [0, 1]
663       end
664     end
665     context '複数コマでヨソのコミックも混じっているとき' do
666       it 'ストーリーから同一コミックのtだけを収集している' do
667         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
668         r = Story.collect_t @story
669         r.sort.should eq [0, 1]
670       end
671     end
672   end
673   describe 'tチェックに於いて' do
674     before do
675       @comic = FactoryGirl.create :comic, :author_id => @author.id
676       @panel = FactoryGirl.create :panel, :author_id => @author.id
677       @story = FactoryGirl.build :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
678     end
679     context 'つつがなく終わるとき' do
680       it 't収集を依頼している' do
681         Story.should_receive(:collect_t).with(any_args).exactly(1)
682         Story.stub(:collect_t).with(any_args).and_return([])
683         Story.stub(:serial?).with(any_args).and_return(true)
684         r = Story.validate_t @story
685       end
686       it '収集したtをシリアライズチェック依頼している' do
687         Story.stub(:collect_t).with(any_args).and_return([])
688         Story.should_receive(:serial?).with(any_args).exactly(1)
689         Story.stub(:serial?).with(any_args).and_return(true)
690         r = Story.validate_t @story
691       end
692     end
693     #実データでチェック
694     #依頼チェックだけでは不安なので最低限のチェックを
695     context '新規のとき' do
696       it '一件だけで正常通過している' do
697         @story = FactoryGirl.build :story, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id, :t => 0
698         r = Story.validate_t @story
699         r.should be_true 
700       end
701     end
702     context '既存のとき' do
703       it '2件目を作っても正常通過している' do
704         @story = FactoryGirl.create :story, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id, :t => 0
705         @story2 = FactoryGirl.build :story, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id, :t => 1
706         r = Story.validate_t @story2
707         r.should be_true 
708       end
709     end
710   end
711   describe '挿入シフトに於いて' do
712     before do
713       @comic = FactoryGirl.create :comic, :author_id => @author.id
714       @panel = FactoryGirl.create :panel, :author_id => @author.id
715     end
716     context '依頼チェック' do
717       #テーブルが空で0に挿入
718       it 'Updateを依頼している' do
719         Story.stub(:update_all).with(any_args)
720         Story.should_receive(:update_all).with(any_args).exactly(1)
721         @story = FactoryGirl.build :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
722         @story.insert_shift
723       end
724     end
725     context 'テーブルに1件(t:0)で0に挿入したとき' do
726       before do
727         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
728         @story2 = FactoryGirl.build :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
729       end
730       it '既存の行を1にシフトしている' do
731         @story2.insert_shift
732         l = Story.find :all
733         l.first.t.should eq 1
734       end
735       it 'これから挿入するt(0)が欠番になっている' do
736         @story2.insert_shift
737         l = Story.find(:all).map {|s| s.t }
738         l.include?(0).should_not be_true
739       end
740     end
741     context 'テーブルに2件(t:0,1)で1に挿入したとき' do
742       before do
743         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
744         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
745         @story3 = FactoryGirl.build :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
746       end
747       it '既存のt1を2にシフトしてこれから挿入するt(1)が欠番になっている' do
748         @story3.insert_shift
749         l = Story.find(:all).map {|s| s.t }
750         l.sort.should eq [0, 2]
751       end
752     end
753     context 'テーブルに5件(t:0,1,2,3,4)で2に挿入したとき' do
754       before do
755         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
756         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
757         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
758         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
759         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
760         @story6 = FactoryGirl.build :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
761       end
762       it '既存のt1を2にシフトしてこれから挿入するt(1)が欠番になっている' do
763         @story6.insert_shift
764         l = Story.find(:all).map {|s| s.t }
765         l.sort.should eq [0, 1, 3, 4, 5]
766       end
767     end
768     context '先ほどのケース+他のコミック1件で挿入したとき' do
769       before do
770         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
771         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
772         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
773         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
774         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
775         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
776         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
777         @story6 = FactoryGirl.build :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
778       end
779       it '既存のt1を2にシフトしてこれから挿入するt(1)が欠番になっている' do
780         @story6.insert_shift
781         l = Story.find(:all, :conditions => ['comic_id = ?', @comic.id]).map {|s| s.t }
782         l.sort.should eq [0, 1, 3, 4, 5]
783       end
784       it '他のコミックに影響がない' do
785         ot = @storyc2.t
786         @story6.insert_shift
787         @storyc2.reload
788         @storyc2.t.should eq ot
789       end
790     end
791   end
792   describe '少ない方に移動に於いて' do
793     before do
794       @comic = FactoryGirl.create :comic, :author_id => @author.id
795       @panel = FactoryGirl.create :panel, :author_id => @author.id
796     end
797     context '依頼チェック' do
798       it 'Updateを依頼している' do
799         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
800         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
801         Story.stub(:update_all).with(any_args)
802         Story.should_receive(:update_all).with(any_args).exactly(1)
803         ot = @story2.t
804         @story2.t = 0
805         @story2.lesser_shift ot
806       end
807     end
808     context 'テーブルに2件(t:0,1)で1を0に移動したとき' do
809       before do
810         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
811         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
812         @ot = @story2.t
813         @story2.t = 0
814       end
815       it '既存のt0を1にシフトしてこれから挿入するt(0)が欠番になっている' do
816         #移動させたい行はそのまま残る
817         @story2.lesser_shift @ot
818         l = Story.find(:all).map {|s| s.t }
819         l.sort.should eq [1, 1]
820       end
821       it '既存のt0を1にシフトしている' do
822         @story2.lesser_shift @ot
823         @story.reload
824         @story.t.should eq 1
825       end
826     end
827     context 'テーブルに3件(t:0,1,2)で2を1に移動したとき' do
828       before do
829         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
830         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
831         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
832         @ot = @story3.t
833         @story3.t = 1
834       end
835       it '既存のt1を2にシフトしてこれから挿入するt(1)が欠番になっている' do
836         #移動させたい行はそのまま残る
837         @story3.lesser_shift @ot
838         l = Story.find(:all).map {|s| s.t }
839         l.sort.should eq [0, 2, 2]
840       end
841       it '既存のt1を2にシフトしている' do
842         @story3.lesser_shift @ot
843         @story2.reload
844         @story2.t.should eq 2
845       end
846     end
847     context 'テーブルに5件(t:0,1,2,3,4)で3を1に移動したとき' do
848       before do
849         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
850         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
851         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
852         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
853         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
854         @ot = @story4.t
855         @story4.t = 1
856       end
857       it 'これから挿入するt(1)が欠番になっている' do
858         #移動させたい行はそのまま残る
859         @story4.lesser_shift @ot
860         l = Story.find(:all).map {|s| s.t }
861         l.sort.should eq [0, 2, 3, 3, 4]
862       end
863       it '既存のt0には変化がない' do
864         @story4.lesser_shift @ot
865         @story.reload
866         @story.t.should eq 0
867       end
868       it '既存のt4には変化がない' do
869         @story4.lesser_shift @ot
870         @story5.reload
871         @story5.t.should eq 4
872       end
873       it '既存のt1を2にシフトしている' do
874         @story4.lesser_shift @ot
875         @story2.reload
876         @story2.t.should eq 2
877       end
878       it '既存のt2を3にシフトしている' do
879         @story4.lesser_shift @ot
880         @story3.reload
881         @story3.t.should eq 3
882       end
883     end
884     context '先ほどのケース+他のコミック1件で挿入したとき' do
885       before do
886         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
887         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
888         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
889         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
890         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
891         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
892         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
893         @ot = @story4.t
894         @story4.t = 1
895       end
896       it 'これから挿入するt(1)が欠番になっている' do
897         @story4.lesser_shift @ot
898         l = Story.find(:all).map {|s| s.t }
899         l.sort.should eq [0, 0, 2, 3, 3, 4]
900       end
901       it '既存のt0には変化がない' do
902         @story4.lesser_shift @ot
903         @story.reload
904         @story.t.should eq 0
905       end
906       it '既存のt4には変化がない' do
907         @story4.lesser_shift @ot
908         @story5.reload
909         @story5.t.should eq 4
910       end
911       it '既存のt1を2にシフトしている' do
912         @story4.lesser_shift @ot
913         @story2.reload
914         @story2.t.should eq 2
915       end
916       it '既存のt2を3にシフトしている' do
917         @story4.lesser_shift @ot
918         @story3.reload
919         @story3.t.should eq 3
920       end
921       it '他のコミックに影響がない' do
922         @story4.lesser_shift @ot
923         @storyc2.reload
924         @storyc2.t.should eq 0
925       end
926     end
927     #例外ケース。
928     #負のときは0として正常扱い
929     context 'テーブルに2件(t:0,1)で1を-1に移動したとき' do
930       before do
931         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
932         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
933         @ot = @story2.t
934         @story2.t = -1
935       end
936       it '既存のt0を1にシフトしてこれから挿入するt(0)が欠番になっている' do
937         #移動させたい行はそのまま残る
938         @story2.lesser_shift @ot
939         l = Story.find(:all).map {|s| s.t }
940         l.sort.should eq [1, 1]
941       end
942       it '既存のt0を1にシフトしている' do
943         @story2.lesser_shift @ot
944         @story.reload
945         @story.t.should eq 1
946       end
947       it '既存のt1は0に補正されている' do
948         @story2.lesser_shift @ot
949         @story2.t.should eq 0
950       end
951     end
952   end
953   describe '大きい方に移動に於いて' do
954     before do
955       @comic = FactoryGirl.create :comic, :author_id => @author.id
956       @panel = FactoryGirl.create :panel, :author_id => @author.id
957     end
958     context '依頼チェック' do
959       it 'Updateを依頼している' do
960         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
961         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
962         Story.stub(:update_all).with(any_args)
963         Story.should_receive(:update_all).with(any_args).exactly(1)
964         ot = @story.t
965         @story.t = 1
966         @story.higher_shift ot
967       end
968     end
969     context 'テーブルに2件(t:0,1)で0を1に移動したとき' do
970       before do
971         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
972         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
973         @ot = @story.t
974         @story.t = 1
975       end
976       it '既存のt1を0にシフトしてこれから挿入するt(1)が欠番になっている' do
977         #移動させたい行はそのまま残る
978         @story.higher_shift @ot
979         l = Story.find(:all).map {|s| s.t }
980         l.sort.should eq [0, 0]
981       end
982       it '既存のt1を0にシフトしている' do
983         @story.higher_shift @ot
984         @story2.reload
985         @story2.t.should eq 0
986       end
987     end
988     context 'テーブルに3件(t:0,1,2)で0を1に移動したとき' do
989       before do
990         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
991         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
992         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
993         @ot = @story.t
994         @story.t = 1
995       end
996       it '既存のt1を0にシフトしてこれから挿入するt(1)が欠番になっている' do
997         #移動させたい行はそのまま残る
998         @story.higher_shift @ot
999         l = Story.find(:all).map {|s| s.t }
1000         l.sort.should eq [0, 0, 2]
1001       end
1002       it '既存のt1を0にシフトしている' do
1003         @story.higher_shift @ot
1004         @story2.reload
1005         @story2.t.should eq 0
1006       end
1007     end
1008     context 'テーブルに5件(t:0,1,2,3,4)で1を3に移動したとき' do
1009       before do
1010         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1011         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1012         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1013         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1014         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1015         @ot = @story2.t
1016         @story2.t = 3
1017       end
1018       it 'これから挿入するt(3)が欠番になっている' do
1019         #移動させたい行はそのまま残る
1020         @story2.higher_shift @ot
1021         l = Story.find(:all).map {|s| s.t }
1022         l.sort.should eq [0, 1, 1, 2, 4]
1023       end
1024       it '既存のt0には変化がない' do
1025         @story2.higher_shift @ot
1026         @story.reload
1027         @story.t.should eq 0
1028       end
1029       it '既存のt4には変化がない' do
1030         @story2.higher_shift @ot
1031         @story5.reload
1032         @story5.t.should eq 4
1033       end
1034       it '既存のt2を1にシフトしている' do
1035         @story2.higher_shift @ot
1036         @story3.reload
1037         @story3.t.should eq 1
1038       end
1039       it '既存のt3を2にシフトしている' do
1040         @story2.higher_shift @ot
1041         @story4.reload
1042         @story4.t.should eq 2
1043       end
1044     end
1045     context '先ほどのケース+他のコミック1件で挿入したとき' do
1046       before do
1047         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
1048         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
1049         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1050         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1051         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1052         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1053         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1054         @ot = @story2.t
1055         @story2.t = 3
1056       end
1057       it 'これから挿入するt(3)が欠番になっている' do
1058         #移動させたい行はそのまま残る
1059         @story2.higher_shift @ot
1060         l = Story.find(:all).map {|s| s.t }
1061         l.sort.should eq [0, 0, 1, 1, 2, 4]
1062       end
1063       it '既存のt0には変化がない' do
1064         @story2.higher_shift @ot
1065         @story.reload
1066         @story.t.should eq 0
1067       end
1068       it '既存のt4には変化がない' do
1069         @story2.higher_shift @ot
1070         @story5.reload
1071         @story5.t.should eq 4
1072       end
1073       it '既存のt2を1にシフトしている' do
1074         @story2.higher_shift @ot
1075         @story3.reload
1076         @story3.t.should eq 1
1077       end
1078       it '既存のt3を2にシフトしている' do
1079         @story2.higher_shift @ot
1080         @story4.reload
1081         @story4.t.should eq 2
1082       end
1083       it '他のコミックに影響がない' do
1084         @story2.higher_shift @ot
1085         @storyc2.reload
1086         @storyc2.t.should eq 0
1087       end
1088     end
1089     #例外ケース。
1090     #max超えたときはmaxとして正常扱い
1091     context 'テーブルに2件(t:0,1)で0を2に移動したとき' do
1092       before do
1093         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1094         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1095         @ot = @story.t
1096         @story.t = 2
1097       end
1098       it '既存のt1を0にシフトしてこれから挿入するt(1)が欠番になっている' do
1099         #移動させたい行はそのまま残る
1100         @story.higher_shift @ot
1101         l = Story.find(:all).map {|s| s.t }
1102         l.sort.should eq [0, 0]
1103       end
1104       it '既存のt1を0にシフトしている' do
1105         @story.higher_shift @ot
1106         @story2.reload
1107         @story2.t.should eq 0
1108       end
1109       it '既存のt0は1に補正されている' do
1110         @story.higher_shift @ot
1111         @story.t.should eq 1
1112       end
1113     end
1114   end
1115   describe '入れ替えに於いて' do
1116     before do
1117       @comic = FactoryGirl.create :comic, :author_id => @author.id
1118       @panel = FactoryGirl.create :panel, :author_id => @author.id
1119       @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1120       @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1121     end
1122     context '新tが旧tより小さいとき' do
1123       it '少ない方に移動を依頼している' do
1124         Story.any_instance.stub(:lesser_shift).with(any_args)
1125         Story.any_instance.should_receive(:lesser_shift).with(any_args).exactly(1)
1126         ot = @story2.t
1127         @story2.t = 0
1128         @story2.update_shift ot
1129       end
1130     end
1131     context '新tが旧tより大きいとき' do
1132       it '大きい方に移動を依頼している' do
1133         Story.any_instance.stub(:higher_shift).with(any_args)
1134         Story.any_instance.should_receive(:higher_shift).with(any_args).exactly(1)
1135         ot = @story.t
1136         @story.t = 1
1137         @story.update_shift ot
1138       end
1139     end
1140   end
1141   describe '順序入れ替えに於いて' do
1142     before do
1143       @comic = FactoryGirl.create :comic, :author_id => @author.id
1144       @panel = FactoryGirl.create :panel, :author_id => @author.id
1145     end
1146     context 'オブジェクトが新規でtが空のとき' do
1147       it '末尾追加としてtを補充依頼している' do
1148         @story = FactoryGirl.build :story, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1149         Story.stub(:new_t).with(any_args).and_return(0)
1150         Story.should_receive(:new_t).with(any_args).exactly(1)
1151         @story.t = nil
1152         r = @story.rotate
1153       end
1154     end
1155     context 'オブジェクトが新規でtが設定されているとき' do
1156       it '挿入追加として挿入シフトを依頼している' do
1157         @story = FactoryGirl.build :story, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1158         Story.any_instance.stub(:insert_shift).with(any_args)
1159         Story.any_instance.should_receive(:insert_shift).with(any_args).exactly(1)
1160         @story.t = 0
1161         r = @story.rotate
1162       end
1163     end
1164     context 'オブジェクトが新規でなくtが設定されているとき' do
1165       it 'コマ移動として入れ替えを依頼している' do
1166         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1167         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1168         Story.any_instance.stub(:update_shift).with(any_args)
1169         Story.any_instance.should_receive(:update_shift).with(1).exactly(1)
1170         @story2.t = 0
1171         r = @story.rotate 1
1172       end
1173     end
1174     context 'オブジェクトが新規でなくtが空のとき' do
1175       it '入れ替えもシフトもせず、tを空のままにしている' do
1176         #結果、tに欠番が生じてシリアライズチェックでひっかかる
1177       end
1178     end
1179   end
1180   describe '編集許可に於いて' do
1181     before do
1182       @comic = FactoryGirl.create :comic, :author_id => @author.id
1183       @panel = FactoryGirl.create :panel, :author_id => @author.id
1184       @story = FactoryGirl.build :story, :t => nil, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1185     end
1186     context 'つつがなく終わるとき' do
1187       it 'trueを返す' do
1188         r = @story.allow?
1189         r.should be_true
1190       end
1191     end
1192     context 'コミックで引っかかるとき' do
1193       it 'falseを返す' do
1194         @story.comic_id = nil
1195         r = @story.allow?
1196         r.should be_false
1197       end
1198       it 'falseを返す' do
1199         Comic.any_instance.stub(:own?).with(any_args).and_return(false)
1200         r = @story.allow?
1201         r.should be_false
1202       end
1203     end
1204     context 'コマで引っかかるとき' do
1205       it 'falseを返す' do
1206         @story.panel_id = nil
1207         r = @story.allow?
1208         r.should be_false
1209       end
1210       it 'falseを返す' do
1211         Panel.any_instance.stub(:usable?).with(any_args).and_return(false)
1212         r = @story.allow?
1213         r.should be_false
1214       end
1215     end
1216   end
1217   describe '保存に於いて' do
1218     before do
1219       @comic = FactoryGirl.create :comic, :author_id => @author.id
1220       @panel = FactoryGirl.create :panel, :author_id => @author.id
1221       @story = FactoryGirl.build :story, :t => nil, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1222     end
1223     context 'つつがなく終わるとき' do
1224       it '編集許可チェックを依頼している' do
1225         Story.any_instance.stub(:allow?).with(any_args).and_return(true)
1226         Story.any_instance.should_receive(:allow?).with(any_args).exactly(1)
1227         r = @story.store
1228       end
1229       it '順序入れ替えを依頼している' do
1230         Story.any_instance.stub(:rotate).with(any_args).and_return(0)
1231         Story.any_instance.should_receive(:rotate).with(any_args).exactly(1)
1232         Story.any_instance.stub(:save).with(any_args).and_return(true)
1233         Story.stub(:validate_t).with(any_args).and_return(true)
1234         r = @story.store 
1235       end
1236       it '保存を依頼している' do
1237         Story.stub(:new_t).with(any_args).and_return(0)
1238         Story.any_instance.stub(:save).with(any_args).and_return(true)
1239         Story.any_instance.should_receive(:save).with(any_args).exactly(1)
1240         Story.stub(:validate_t).with(any_args).and_return(true)
1241         r = @story.store
1242       end
1243       it 'tのシリアライズチェックを依頼している' do
1244         Story.stub(:new_t).with(any_args).and_return(0)
1245         Story.any_instance.stub(:save).with(any_args).and_return(true)
1246         Story.stub(:validate_t).with(any_args).and_return(true)
1247         Story.should_receive(:validate_t).with(any_args).exactly(1)
1248         r = @story.store
1249       end
1250     end
1251     #入れ替えテストと同じテストを実施。こちらはシフトだけでなく本尊も更新されている
1252     context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で2に挿入したとき' do
1253       before do
1254         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
1255         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
1256         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1257         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1258         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1259         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1260         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1261         @story6 = FactoryGirl.build :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1262       end
1263       it '既存のt0には変化がない' do
1264         @story6.store
1265         @story.reload
1266         @story.t.should eq 0
1267       end
1268       it '既存のt1には変化がない' do
1269         @story6.store
1270         @story2.reload
1271         @story2.t.should eq 1
1272       end
1273       it '既存のt2を3にシフトしている' do
1274         @story6.store
1275         @story3.reload
1276         @story3.t.should eq 3
1277       end
1278       it '既存のt3を4にシフトしている' do
1279         @story6.store
1280         @story4.reload
1281         @story4.t.should eq 4
1282       end
1283       it '既存のt5を5にシフトしている' do
1284         @story6.store
1285         @story5.reload
1286         @story5.t.should eq 5
1287       end
1288       it '新規のt2が作成されている' do
1289         @story6.store
1290         @story6.reload
1291         @story6.t.should eq 2
1292       end
1293       it '他のコミックに影響がない' do
1294         @ot = @storyc2.t
1295         @story6.store
1296         @storyc2.reload
1297         @storyc2.t.should eq @ot
1298       end
1299     end
1300     context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で3を1に移動したとき' do
1301       before do
1302         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
1303         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
1304         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1305         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1306         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1307         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1308         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1309         @ot = @story4.t
1310         @story4.t = 1
1311       end
1312       it '既存のt0には変化がない' do
1313         @story4.store @ot
1314         @story.reload
1315         @story.t.should eq 0
1316       end
1317       it '既存のt4には変化がない' do
1318         @story4.store @ot
1319         @story5.reload
1320         @story5.t.should eq 4
1321       end
1322       it '既存のt1を2にシフトしている' do
1323         @story4.store @ot
1324         @story2.reload
1325         @story2.t.should eq 2
1326       end
1327       it '既存のt2を3にシフトしている' do
1328         @story4.store @ot
1329         @story3.reload
1330         @story3.t.should eq 3
1331       end
1332       it '既存のt3を1にシフトしている' do
1333         @story4.store @ot
1334         @story4.reload
1335         @story4.t.should eq 1
1336       end
1337       it '他のコミックに影響がない' do
1338         @story4.store @ot
1339         @storyc2.reload
1340         @storyc2.t.should eq 0
1341       end
1342     end
1343     context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で1を3に移動したとき' do
1344       before do
1345         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
1346         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
1347         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1348         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1349         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1350         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1351         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1352         @ot = @story2.t
1353         @story2.t = 3
1354       end
1355       it '既存のt0には変化がない' do
1356         @story2.store @ot
1357         @story.reload
1358         @story.t.should eq 0
1359       end
1360       it '既存のt4には変化がない' do
1361         @story2.store @ot
1362         @story5.reload
1363         @story5.t.should eq 4
1364       end
1365       it '既存のt1を3にシフトしている' do
1366         @story2.store @ot
1367         @story2.reload
1368         @story2.t.should eq 3
1369       end
1370       it '既存のt2を1にシフトしている' do
1371         @story2.store @ot
1372         @story3.reload
1373         @story3.t.should eq 1
1374       end
1375       it '既存のt3を2にシフトしている' do
1376         @story2.store @ot
1377         @story4.reload
1378         @story4.t.should eq 2
1379       end
1380       it '他のコミックに影響がない' do
1381         @story2.store @ot
1382         @storyc2.reload
1383         @storyc2.t.should eq 0
1384       end
1385     end
1386     #ロールバックテスト。入れ替えが直接DBをいじるので、すべてのケースで確実にロールバックを確認する
1387     context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で2に挿入したが保存に失敗したとき' do
1388       before do
1389         Story.any_instance.stub(:save).with(any_args).and_return(false)
1390         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
1391         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
1392         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1393         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1394         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1395         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1396         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1397         @story6 = FactoryGirl.build :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1398       end
1399       it '既存のtに変化がない' do
1400         @story6.store
1401         @story.reload
1402         @story.t.should eq 0
1403         @story2.reload
1404         @story2.t.should eq 1
1405         @story3.reload
1406         @story3.t.should eq 2
1407         @story4.reload
1408         @story4.t.should eq 3
1409         @story5.reload
1410         @story5.t.should eq 4
1411         @storyc2.reload
1412         @storyc2.t.should eq 0
1413       end
1414       it 'falseを返す' do
1415         r = @story6.store
1416         r.should be_false
1417       end
1418     end
1419     context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で3を1に移動したがシリアルチェックに失敗したとき' do
1420       before do
1421         Story.stub(:validate_t).with(any_args).and_return(false)
1422         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
1423         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
1424         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1425         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1426         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1427         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1428         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1429         @ot = @story4.t
1430         @story4.t = 1
1431       end
1432       it '既存のtに変化がない' do
1433         @story4.store @ot
1434         @story.reload
1435         @story.t.should eq 0
1436         @story2.reload
1437         @story2.t.should eq 1
1438         @story3.reload
1439         @story3.t.should eq 2
1440         @story4.reload
1441         @story4.t.should eq 3
1442         @story5.reload
1443         @story5.t.should eq 4
1444         @storyc2.reload
1445         @storyc2.t.should eq 0
1446       end
1447       it 'falseを返す' do
1448         r = @story4.store @ot
1449         r.should be_false
1450       end
1451       it 'tにエラーメッセージが入っている' do
1452         @story4.store @ot
1453         @story4.errors[:t].should_not be_empty
1454         @story4.valid?.should be_true
1455       end
1456     end
1457     context '編集不可だったとき' do
1458       before do
1459         @story = FactoryGirl.build :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1460         Story.any_instance.stub(:allow?).and_return(false)
1461       end
1462       it '403Forbidden例外を返す' do
1463         lambda{
1464           @story.store
1465         }.should raise_error(ActiveRecord::Forbidden)
1466       end
1467     end
1468   end
1469   describe '切り詰め処理つき削除に於いて' do
1470     before do
1471       @comic = FactoryGirl.create :comic, :author_id => @author.id
1472       @panel = FactoryGirl.create :panel, :author_id => @author.id
1473       @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1474     end
1475     context 'つつがなく終わるとき' do
1476       it '削除される' do
1477         lambda{
1478           @story.destroy_and_shorten
1479         }.should change(Story, :count ).by(-1)
1480       end
1481     end
1482     #連携テスト。切り詰めが直接DBをいじる
1483     context '2件で先頭を削除したとき' do
1484       before do
1485         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1486       end
1487       it '行が削除される' do
1488         lambda{
1489           @story.destroy_and_shorten
1490         }.should change(Story, :count ).by(-1)
1491       end
1492       it '先頭は削除される' do
1493         @story.destroy_and_shorten
1494         lambda{
1495           Story.find @story.id
1496         }.should raise_error(ActiveRecord::RecordNotFound)
1497       end
1498       it '2件目は前に詰められる' do
1499         @story.destroy_and_shorten
1500         @story2.reload
1501         @story2.t.should eq 0
1502       end
1503     end
1504     context '3件で先頭を削除したとき' do
1505       before do
1506         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1507         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1508       end
1509       it '行が削除される' do
1510         lambda{
1511           @story.destroy_and_shorten
1512         }.should change(Story, :count ).by(-1)
1513       end
1514       it '先頭は削除される' do
1515         @story.destroy_and_shorten
1516         lambda{
1517           Story.find @story.id
1518         }.should raise_error(ActiveRecord::RecordNotFound)
1519       end
1520       it '2件目は前に詰められる' do
1521         @story.destroy_and_shorten
1522         @story2.reload
1523         @story2.t.should eq 0
1524       end
1525       it '3件目は前に詰められる' do
1526         @story.destroy_and_shorten
1527         @story3.reload
1528         @story3.t.should eq 1
1529       end
1530     end
1531     context '5件で3件目を削除したとき' do
1532       before do
1533         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1534         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1535         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1536         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1537       end
1538       it '行が削除される' do
1539         lambda{
1540           @story3.destroy_and_shorten
1541         }.should change(Story, :count ).by(-1)
1542       end
1543       it '1件目は変化がない' do
1544         @story3.destroy_and_shorten
1545         @story.reload
1546         @story.t.should eq 0
1547       end
1548       it '2件目は変化がない' do
1549         @story3.destroy_and_shorten
1550         @story2.reload
1551         @story2.t.should eq 1
1552       end
1553       it '3件目は削除される' do
1554         @story3.destroy_and_shorten
1555         lambda{
1556           Story.find @story3.id
1557         }.should raise_error(ActiveRecord::RecordNotFound)
1558       end
1559       it '4件目は前に詰められる' do
1560         @story3.destroy_and_shorten
1561         @story4.reload
1562         @story4.t.should eq 2
1563       end
1564       it '5件目は前に詰められる' do
1565         @story3.destroy_and_shorten
1566         @story5.reload
1567         @story5.t.should eq 3
1568       end
1569     end
1570     #ロールバックテスト。切り詰めが直接DBをいじるので、すべてのケースで確実にロールバックを確認する
1571   end
1572 end