OSDN Git Service

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