OSDN Git Service

t#29400
[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       end
368       it '通常は全件(5件)を返す' do
369         r = Story.mylist @author, 5, 0
370         r.should have(5).items 
371       end
372     end
373   end
374   
375   describe '編集取得に於いて' do
376     before do
377       @comic = FactoryGirl.create :comic, :author_id => @author.id
378       @panel = FactoryGirl.create :panel, :author_id => @author.id
379       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
380     end
381     context 'つつがなく終わるとき' do\r
382       it '単体取得オプションを利用している' do\r
383         Story.stub(:show_opt).with(any_args).and_return({})\r
384         Story.should_receive(:show_opt).with(any_args).exactly(1)\r
385         r = Story.edit @story.id, @author
386       end\r
387       it '所持判定を問い合わせている' do\r
388         Story.any_instance.stub(:own?).with(any_args).and_return(true)\r
389         Story.any_instance.should_receive(:own?).with(any_args).exactly(1)\r
390         r = Story.edit @story.id, @author
391       end\r
392     end\r
393     it '指定のストーリーを返す' do
394       l = Story.edit @story.id, @author
395       l.should eq @story
396     end
397     context '他人のストーリーを開こうとしたとき' do
398       it '403Forbidden例外を返す' do
399         Story.any_instance.stub(:own?).and_return(false)
400         lambda{
401           Story.edit @story.id, @author
402         }.should raise_error(ActiveRecord::Forbidden)
403       end
404     end
405     context '存在しないストーリーを開こうとしたとき' do
406       it '404RecordNotFound例外を返す' do
407         lambda{
408           Story.edit 110, @author
409         }.should raise_error(ActiveRecord::RecordNotFound)
410       end
411     end
412   end
413   
414   describe '単体取得オプションに於いて' do
415     it 'includeキーを含んでいる' do
416       r = Story.show_opt
417       r.has_key?(:include).should be_true
418     end
419     it '3つの項目を含んでいる' do
420       r = Story.show_opt[:include]
421       r.should have(3).items
422     end
423     it 'コミックを含んでいる' do
424       r = Story.show_opt[:include]
425       r.has_key?(:comic).should be_true
426     end
427       it 'コミックは作家を含んでいる' do
428         r = Story.show_opt[:include]
429         r[:comic].has_key?(:author).should be_true
430       end
431     it '作家を含んでいる' do
432       r = Story.show_opt[:include]
433       r.has_key?(:author).should be_true
434     end
435     it 'コマを含んでいる' do
436       r = Story.show_opt[:include]
437       r.has_key?(:panel).should be_true
438     end
439       it 'コマは作家を含んでいる' do
440         r = Story.show_opt[:include]
441         r[:panel].has_key?(:author).should be_true
442       end
443       it 'コマはコマ絵を含んでいる' do
444         r = Story.show_opt[:include]
445         r[:panel].has_key?(:panel_pictures).should be_true
446       end
447         it 'コマ絵は実素材を含んでいる' do
448           r = Story.show_opt[:include]
449           r[:panel][:panel_pictures].has_key?(:picture).should be_true
450         end
451           it '実素材は絵師を含んでいる' do
452             r = Story.show_opt[:include]
453             r[:panel][:panel_pictures][:picture].has_key?(:artist).should be_true
454           end
455           it '実素材はライセンスを含んでいる' do
456             r = Story.show_opt[:include]
457             r[:panel][:panel_pictures][:picture].has_key?(:license).should be_true
458           end
459       it 'コマはフキダシを含んでいる' do
460         r = Story.show_opt[:include]
461         r[:panel].has_key?(:speech_balloons).should be_true
462       end
463         it 'フキダシはフキダシ枠を含んでいる' do
464           r = Story.show_opt[:include]
465           r[:panel][:speech_balloons].has_key?(:balloons).should be_true
466         end
467         it 'フキダシはセリフを含んでいる' do
468           r = Story.show_opt[:include]
469           r[:panel][:speech_balloons].has_key?(:speeches).should be_true
470         end
471   end
472   describe 'json単体取得オプションに於いて' do
473   end
474   
475   describe 'ストーリーのjson出力に於いて' do
476     before do\r
477       #コマを作成しておく。\r
478       @panel = FactoryGirl.create :panel, :author_id => @author.id\r
479       @pp = FactoryGirl.create :panel_picture, :panel_id => @panel.id, :t => 1, :width => @p.width, :height => @p.height\r
480       @sb = @panel.speech_balloons.create(\r
481         FactoryGirl.attributes_for(:speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @sbt.id, :t => 0)\r
482       )\r
483       @gc = @panel.ground_colors.create(\r
484         FactoryGirl.attributes_for(:ground_color, :panel_id => @panel.id, :color_id => @color.id)\r
485       )\r
486       @gp = @panel.ground_pictures.create(\r
487         FactoryGirl.attributes_for(:ground_picture, :panel_id => @panel.id, :picture_id => @p.id)\r
488       )\r
489       @pc = @panel.panel_colors.create(\r
490         FactoryGirl.attributes_for(:panel_color, :panel_id => @panel.id, :code => 0xff0000)\r
491       )\r
492       @panel.reload\r
493       @comic = FactoryGirl.create :comic, :author_id => @author.id
494       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
495     end\r
496     context '事前チェックする' do
497       before do\r
498         Panel.any_instance.stub(:elements).and_return('{}')
499       end\r
500       it 'コマ要素のjson出力を依頼している' do\r
501         Panel.any_instance.stub(:visible?).with(any_args).and_return(true)
502         Panel.any_instance.should_receive(:elements).with(any_args).exactly(1)\r
503         r = @story.story_as_json @author
504       end\r
505     end\r
506     it 'json textを返している' do\r
507       r = JSON.parse @story.story_as_json(@author)\r
508       r.is_a?(Hash).should be_true\r
509     end\r
510     it 'comic,author,panel,コマ要素を含んでいる' do\r
511       r = JSON.parse @story.story_as_json(@author)\r
512       r.has_key?('comic').should be_true\r
513       r['comic'].has_key?('author').should be_true\r
514       r.has_key?('author').should be_true\r
515       r.has_key?('panel').should be_true\r
516       r['panel'].has_key?('author').should be_true\r
517     end\r
518     context 'コマ閲覧許可のとき' do
519       before do\r
520         Panel.any_instance.stub(:visible?).with(any_args).and_return(true)
521       end\r
522       it 'コマ要素にコマ要素を追加している' do\r
523         r = JSON.parse @story.story_as_json(@author)\r
524         r['panel'].has_key?('elements').should be_true\r
525         r['panel']['elements'].should_not be_empty\r
526       end\r
527     end\r
528     context 'コマ閲覧不許可のとき' do
529       before do\r
530         Panel.any_instance.stub(:visible?).with(any_args).and_return(false)
531       end\r
532       it 'コマ要素にデータを含ませない' do\r
533         r = JSON.parse @story.story_as_json(@author)\r
534         r['panel'].has_key?('elements').should be_false\r
535       end\r
536     end\r
537   end
538   
539   describe 't補充値に於いて' do
540     before do
541       @comic = FactoryGirl.create :comic, :author_id => @author.id
542       @panel = FactoryGirl.create :panel, :author_id => @author.id
543     end
544     
545     context 'コミック初のコマなら' do
546       it '0を補充値とする' do
547         @story = FactoryGirl.build :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
548         @story.t = nil
549         r = Story.new_t @story.comic_id
550         r.should eq 0
551       end
552     end
553     context 'コミックに一個コマがあるとき' do
554       it '1を補充値とする' do
555         FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 0
556         @story = FactoryGirl.build :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
557         @story.t = nil
558         r = Story.new_t @story.comic_id
559         r.should eq 1
560       end
561     end
562     context 'コミックに2個コマがあるとき' do
563       it '2を補充値とする' do
564         FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 0
565         FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id, :t => 1
566         @story = FactoryGirl.build :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
567         @story.t = nil
568         r = Story.new_t @story.comic_id
569         r.should eq 2
570       end
571     end
572   end
573   describe 'シリアライズチェックに於いて' do
574     context 'つつがなく終わるとき' do
575       it '0からシリアライズされているならTrueを返す' do
576         r = Story.serial? [0, 1, 2]
577         r.should be_true
578       end
579       it '見た目はシリアライズされてなくてもソート結果が無事ならtrueを返す' do
580         r = Story.serial? [0, 2, 1]
581         r.should be_true
582       end
583       it '見た目はシリアライズされてなくてもソート結果が無事ならtrueを返す' do
584         r = Story.serial? [ 2, 1, 4, 3, 0]
585         r.should be_true
586       end
587     end
588     context '異常なとき' do
589       it '0から始まらないならFalseを返す' do
590         r = Story.serial? [1, 2, 3]
591         r.should be_false
592       end
593       it '連続していないならFalseを返す' do
594         r = Story.serial? [0, 1, 2, 4]
595         r.should be_false
596       end
597       it '連続していないならFalseを返す' do
598         r = Story.serial? [0, 1, 2, 4, 5]
599         r.should be_false
600       end
601     end
602   end
603   describe 't収集に於いて' do
604     before do
605       @comic = FactoryGirl.create :comic, :author_id => @author.id
606       @panel = FactoryGirl.create :panel, :author_id => @author.id
607       @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
608       @comic2 = FactoryGirl.create :comic, :author_id => @author.id
609       @c2story = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
610     end
611     context 'つつがなく終わるとき' do
612       it 'ストーリーから同一コミックのtだけを収集している' do
613         r = Story.collect_t @story
614         r.should eq [0]
615       end
616     end
617     context '複数コマのとき' do
618       it 'ストーリーから同一コミックのtだけを収集している' do
619         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
620         r = Story.collect_t @story
621         r.sort.should eq [0, 1]
622       end
623     end
624     context '複数コマでヨソのコミックも混じっているとき' do
625       it 'ストーリーから同一コミックのtだけを収集している' do
626         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
627         r = Story.collect_t @story
628         r.sort.should eq [0, 1]
629       end
630     end
631   end
632   describe 'tチェックに於いて' do
633     before do
634       @comic = FactoryGirl.create :comic, :author_id => @author.id
635       @panel = FactoryGirl.create :panel, :author_id => @author.id
636       @story = FactoryGirl.build :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
637     end
638     context 'つつがなく終わるとき' do
639       it 't収集を依頼している' do
640         Story.should_receive(:collect_t).with(any_args).exactly(1)
641         Story.stub(:collect_t).with(any_args).and_return([])
642         Story.stub(:serial?).with(any_args).and_return(true)
643         r = Story.validate_t @story
644       end
645       it '収集したtをシリアライズチェック依頼している' do
646         Story.stub(:collect_t).with(any_args).and_return([])
647         Story.should_receive(:serial?).with(any_args).exactly(1)
648         Story.stub(:serial?).with(any_args).and_return(true)
649         r = Story.validate_t @story
650       end
651     end
652     #実データでチェック
653     #依頼チェックだけでは不安なので最低限のチェックを
654     context '新規のとき' do
655       it '一件だけで正常通過している' do
656         @story = FactoryGirl.build :story, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id, :t => 0
657         r = Story.validate_t @story
658         r.should be_true 
659       end
660     end
661     context '既存のとき' do
662       it '2件目を作っても正常通過している' do
663         @story = FactoryGirl.create :story, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id, :t => 0
664         @story2 = FactoryGirl.build :story, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id, :t => 1
665         r = Story.validate_t @story2
666         r.should be_true 
667       end
668     end
669   end
670   describe '挿入シフトに於いて' do
671     before do
672       @comic = FactoryGirl.create :comic, :author_id => @author.id
673       @panel = FactoryGirl.create :panel, :author_id => @author.id
674     end
675     context '依頼チェック' do
676       #テーブルが空で0に挿入
677       it 'Updateを依頼している' do
678         Story.stub(:update_all).with(any_args)
679         Story.should_receive(:update_all).with(any_args).exactly(1)
680         @story = FactoryGirl.build :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
681         @story.insert_shift
682       end
683     end
684     context 'テーブルに1件(t:0)で0に挿入したとき' do
685       before do
686         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
687         @story2 = FactoryGirl.build :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
688       end
689       it '既存の行を1にシフトしている' do
690         @story2.insert_shift
691         l = Story.find :all
692         l.first.t.should eq 1
693       end
694       it 'これから挿入するt(0)が欠番になっている' do
695         @story2.insert_shift
696         l = Story.find(:all).map {|s| s.t }
697         l.include?(0).should_not be_true
698       end
699     end
700     context 'テーブルに2件(t:0,1)で1に挿入したとき' do
701       before do
702         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
703         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
704         @story3 = FactoryGirl.build :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
705       end
706       it '既存のt1を2にシフトしてこれから挿入するt(1)が欠番になっている' do
707         @story3.insert_shift
708         l = Story.find(:all).map {|s| s.t }
709         l.sort.should eq [0, 2]
710       end
711     end
712     context 'テーブルに5件(t:0,1,2,3,4)で2に挿入したとき' do
713       before do
714         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
715         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
716         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
717         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
718         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
719         @story6 = FactoryGirl.build :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
720       end
721       it '既存のt1を2にシフトしてこれから挿入するt(1)が欠番になっている' do
722         @story6.insert_shift
723         l = Story.find(:all).map {|s| s.t }
724         l.sort.should eq [0, 1, 3, 4, 5]
725       end
726     end
727     context '先ほどのケース+他のコミック1件で挿入したとき' do
728       before do
729         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
730         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
731         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
732         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
733         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
734         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
735         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
736         @story6 = FactoryGirl.build :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
737       end
738       it '既存のt1を2にシフトしてこれから挿入するt(1)が欠番になっている' do
739         @story6.insert_shift
740         l = Story.find(:all, :conditions => ['comic_id = ?', @comic.id]).map {|s| s.t }
741         l.sort.should eq [0, 1, 3, 4, 5]
742       end
743       it '他のコミックに影響がない' do
744         ot = @storyc2.t
745         @story6.insert_shift
746         @storyc2.reload
747         @storyc2.t.should eq ot
748       end
749     end
750   end
751   describe '少ない方に移動に於いて' do
752     before do
753       @comic = FactoryGirl.create :comic, :author_id => @author.id
754       @panel = FactoryGirl.create :panel, :author_id => @author.id
755     end
756     context '依頼チェック' do
757       it 'Updateを依頼している' do
758         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
759         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
760         Story.stub(:update_all).with(any_args)
761         Story.should_receive(:update_all).with(any_args).exactly(1)
762         ot = @story2.t
763         @story2.t = 0
764         @story2.lesser_shift ot
765       end
766     end
767     context 'テーブルに2件(t:0,1)で1を0に移動したとき' do
768       before do
769         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
770         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
771         @ot = @story2.t
772         @story2.t = 0
773       end
774       it '既存のt0を1にシフトしてこれから挿入するt(0)が欠番になっている' do
775         #移動させたい行はそのまま残る
776         @story2.lesser_shift @ot
777         l = Story.find(:all).map {|s| s.t }
778         l.sort.should eq [1, 1]
779       end
780       it '既存のt0を1にシフトしている' do
781         @story2.lesser_shift @ot
782         @story.reload
783         @story.t.should eq 1
784       end
785     end
786     context 'テーブルに3件(t:0,1,2)で2を1に移動したとき' do
787       before do
788         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
789         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
790         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
791         @ot = @story3.t
792         @story3.t = 1
793       end
794       it '既存のt1を2にシフトしてこれから挿入するt(1)が欠番になっている' do
795         #移動させたい行はそのまま残る
796         @story3.lesser_shift @ot
797         l = Story.find(:all).map {|s| s.t }
798         l.sort.should eq [0, 2, 2]
799       end
800       it '既存のt1を2にシフトしている' do
801         @story3.lesser_shift @ot
802         @story2.reload
803         @story2.t.should eq 2
804       end
805     end
806     context 'テーブルに5件(t:0,1,2,3,4)で3を1に移動したとき' do
807       before do
808         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
809         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
810         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
811         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
812         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
813         @ot = @story4.t
814         @story4.t = 1
815       end
816       it 'これから挿入するt(1)が欠番になっている' do
817         #移動させたい行はそのまま残る
818         @story4.lesser_shift @ot
819         l = Story.find(:all).map {|s| s.t }
820         l.sort.should eq [0, 2, 3, 3, 4]
821       end
822       it '既存のt0には変化がない' do
823         @story4.lesser_shift @ot
824         @story.reload
825         @story.t.should eq 0
826       end
827       it '既存のt4には変化がない' do
828         @story4.lesser_shift @ot
829         @story5.reload
830         @story5.t.should eq 4
831       end
832       it '既存のt1を2にシフトしている' do
833         @story4.lesser_shift @ot
834         @story2.reload
835         @story2.t.should eq 2
836       end
837       it '既存のt2を3にシフトしている' do
838         @story4.lesser_shift @ot
839         @story3.reload
840         @story3.t.should eq 3
841       end
842     end
843     context '先ほどのケース+他のコミック1件で挿入したとき' do
844       before do
845         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
846         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
847         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
848         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
849         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
850         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
851         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
852         @ot = @story4.t
853         @story4.t = 1
854       end
855       it 'これから挿入するt(1)が欠番になっている' do
856         @story4.lesser_shift @ot
857         l = Story.find(:all).map {|s| s.t }
858         l.sort.should eq [0, 0, 2, 3, 3, 4]
859       end
860       it '既存のt0には変化がない' do
861         @story4.lesser_shift @ot
862         @story.reload
863         @story.t.should eq 0
864       end
865       it '既存のt4には変化がない' do
866         @story4.lesser_shift @ot
867         @story5.reload
868         @story5.t.should eq 4
869       end
870       it '既存のt1を2にシフトしている' do
871         @story4.lesser_shift @ot
872         @story2.reload
873         @story2.t.should eq 2
874       end
875       it '既存のt2を3にシフトしている' do
876         @story4.lesser_shift @ot
877         @story3.reload
878         @story3.t.should eq 3
879       end
880       it '他のコミックに影響がない' do
881         @story4.lesser_shift @ot
882         @storyc2.reload
883         @storyc2.t.should eq 0
884       end
885     end
886     #例外ケース。
887     #負のときは0として正常扱い
888     context 'テーブルに2件(t:0,1)で1を-1に移動したとき' do
889       before do
890         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
891         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
892         @ot = @story2.t
893         @story2.t = -1
894       end
895       it '既存のt0を1にシフトしてこれから挿入するt(0)が欠番になっている' do
896         #移動させたい行はそのまま残る
897         @story2.lesser_shift @ot
898         l = Story.find(:all).map {|s| s.t }
899         l.sort.should eq [1, 1]
900       end
901       it '既存のt0を1にシフトしている' do
902         @story2.lesser_shift @ot
903         @story.reload
904         @story.t.should eq 1
905       end
906       it '既存のt1は0に補正されている' do
907         @story2.lesser_shift @ot
908         @story2.t.should eq 0
909       end
910     end
911   end
912   describe '大きい方に移動に於いて' do
913     before do
914       @comic = FactoryGirl.create :comic, :author_id => @author.id
915       @panel = FactoryGirl.create :panel, :author_id => @author.id
916     end
917     context '依頼チェック' do
918       it 'Updateを依頼している' do
919         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
920         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
921         Story.stub(:update_all).with(any_args)
922         Story.should_receive(:update_all).with(any_args).exactly(1)
923         ot = @story.t
924         @story.t = 1
925         @story.higher_shift ot
926       end
927     end
928     context 'テーブルに2件(t:0,1)で0を1に移動したとき' do
929       before do
930         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
931         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
932         @ot = @story.t
933         @story.t = 1
934       end
935       it '既存のt1を0にシフトしてこれから挿入するt(1)が欠番になっている' do
936         #移動させたい行はそのまま残る
937         @story.higher_shift @ot
938         l = Story.find(:all).map {|s| s.t }
939         l.sort.should eq [0, 0]
940       end
941       it '既存のt1を0にシフトしている' do
942         @story.higher_shift @ot
943         @story2.reload
944         @story2.t.should eq 0
945       end
946     end
947     context 'テーブルに3件(t:0,1,2)で0を1に移動したとき' do
948       before do
949         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
950         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
951         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
952         @ot = @story.t
953         @story.t = 1
954       end
955       it '既存のt1を0にシフトしてこれから挿入するt(1)が欠番になっている' do
956         #移動させたい行はそのまま残る
957         @story.higher_shift @ot
958         l = Story.find(:all).map {|s| s.t }
959         l.sort.should eq [0, 0, 2]
960       end
961       it '既存のt1を0にシフトしている' do
962         @story.higher_shift @ot
963         @story2.reload
964         @story2.t.should eq 0
965       end
966     end
967     context 'テーブルに5件(t:0,1,2,3,4)で1を3に移動したとき' do
968       before do
969         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
970         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
971         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
972         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
973         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
974         @ot = @story2.t
975         @story2.t = 3
976       end
977       it 'これから挿入するt(3)が欠番になっている' do
978         #移動させたい行はそのまま残る
979         @story2.higher_shift @ot
980         l = Story.find(:all).map {|s| s.t }
981         l.sort.should eq [0, 1, 1, 2, 4]
982       end
983       it '既存のt0には変化がない' do
984         @story2.higher_shift @ot
985         @story.reload
986         @story.t.should eq 0
987       end
988       it '既存のt4には変化がない' do
989         @story2.higher_shift @ot
990         @story5.reload
991         @story5.t.should eq 4
992       end
993       it '既存のt2を1にシフトしている' do
994         @story2.higher_shift @ot
995         @story3.reload
996         @story3.t.should eq 1
997       end
998       it '既存のt3を2にシフトしている' do
999         @story2.higher_shift @ot
1000         @story4.reload
1001         @story4.t.should eq 2
1002       end
1003     end
1004     context '先ほどのケース+他のコミック1件で挿入したとき' do
1005       before do
1006         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
1007         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
1008         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1009         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1010         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1011         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1012         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1013         @ot = @story2.t
1014         @story2.t = 3
1015       end
1016       it 'これから挿入するt(3)が欠番になっている' do
1017         #移動させたい行はそのまま残る
1018         @story2.higher_shift @ot
1019         l = Story.find(:all).map {|s| s.t }
1020         l.sort.should eq [0, 0, 1, 1, 2, 4]
1021       end
1022       it '既存のt0には変化がない' do
1023         @story2.higher_shift @ot
1024         @story.reload
1025         @story.t.should eq 0
1026       end
1027       it '既存のt4には変化がない' do
1028         @story2.higher_shift @ot
1029         @story5.reload
1030         @story5.t.should eq 4
1031       end
1032       it '既存のt2を1にシフトしている' do
1033         @story2.higher_shift @ot
1034         @story3.reload
1035         @story3.t.should eq 1
1036       end
1037       it '既存のt3を2にシフトしている' do
1038         @story2.higher_shift @ot
1039         @story4.reload
1040         @story4.t.should eq 2
1041       end
1042       it '他のコミックに影響がない' do
1043         @story2.higher_shift @ot
1044         @storyc2.reload
1045         @storyc2.t.should eq 0
1046       end
1047     end
1048     #例外ケース。
1049     #max超えたときはmaxとして正常扱い
1050     context 'テーブルに2件(t:0,1)で0を2に移動したとき' do
1051       before do
1052         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1053         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1054         @ot = @story.t
1055         @story.t = 2
1056       end
1057       it '既存のt1を0にシフトしてこれから挿入するt(1)が欠番になっている' do
1058         #移動させたい行はそのまま残る
1059         @story.higher_shift @ot
1060         l = Story.find(:all).map {|s| s.t }
1061         l.sort.should eq [0, 0]
1062       end
1063       it '既存のt1を0にシフトしている' do
1064         @story.higher_shift @ot
1065         @story2.reload
1066         @story2.t.should eq 0
1067       end
1068       it '既存のt0は1に補正されている' do
1069         @story.higher_shift @ot
1070         @story.t.should eq 1
1071       end
1072     end
1073   end
1074   describe '入れ替えに於いて' do
1075     before do
1076       @comic = FactoryGirl.create :comic, :author_id => @author.id
1077       @panel = FactoryGirl.create :panel, :author_id => @author.id
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     end
1081     context '新tが旧tより小さいとき' do
1082       it '少ない方に移動を依頼している' do
1083         Story.any_instance.stub(:lesser_shift).with(any_args)
1084         Story.any_instance.should_receive(:lesser_shift).with(any_args).exactly(1)
1085         ot = @story2.t
1086         @story2.t = 0
1087         @story2.update_shift ot
1088       end
1089     end
1090     context '新tが旧tより大きいとき' do
1091       it '大きい方に移動を依頼している' do
1092         Story.any_instance.stub(:higher_shift).with(any_args)
1093         Story.any_instance.should_receive(:higher_shift).with(any_args).exactly(1)
1094         ot = @story.t
1095         @story.t = 1
1096         @story.update_shift ot
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     end
1105     context 'オブジェクトが新規でtが空のとき' do
1106       it '末尾追加としてtを補充依頼している' do
1107         @story = FactoryGirl.build :story, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1108         Story.stub(:new_t).with(any_args).and_return(0)
1109         Story.should_receive(:new_t).with(any_args).exactly(1)
1110         @story.t = nil
1111         r = @story.rotate
1112       end
1113     end
1114     context 'オブジェクトが新規でtが設定されているとき' do
1115       it '挿入追加として挿入シフトを依頼している' do
1116         @story = FactoryGirl.build :story, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1117         Story.any_instance.stub(:insert_shift).with(any_args)
1118         Story.any_instance.should_receive(:insert_shift).with(any_args).exactly(1)
1119         @story.t = 0
1120         r = @story.rotate
1121       end
1122     end
1123     context 'オブジェクトが新規でなくtが設定されているとき' do
1124       it 'コマ移動として入れ替えを依頼している' do
1125         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1126         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1127         Story.any_instance.stub(:update_shift).with(any_args)
1128         Story.any_instance.should_receive(:update_shift).with(1).exactly(1)
1129         @story2.t = 0
1130         r = @story.rotate 1
1131       end
1132     end
1133     context 'オブジェクトが新規でなくtが空のとき' do
1134       it '入れ替えもシフトもせず、tを空のままにしている' do
1135         #結果、tに欠番が生じてシリアライズチェックでひっかかる
1136       end
1137     end
1138   end
1139   describe '編集許可に於いて' do
1140     before do
1141       @comic = FactoryGirl.create :comic, :author_id => @author.id
1142       @panel = FactoryGirl.create :panel, :author_id => @author.id
1143       @story = FactoryGirl.build :story, :t => nil, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1144     end
1145     context 'つつがなく終わるとき' do
1146       it 'trueを返す' do
1147         r = @story.allow?
1148         r.should be_true
1149       end
1150     end
1151     context 'コミックで引っかかるとき' do
1152       it 'falseを返す' do
1153         @story.comic_id = nil
1154         r = @story.allow?
1155         r.should be_false
1156       end
1157       it 'falseを返す' do
1158         Comic.any_instance.stub(:own?).with(any_args).and_return(false)
1159         r = @story.allow?
1160         r.should be_false
1161       end
1162     end
1163     context 'コマで引っかかるとき' do
1164       it 'falseを返す' do
1165         @story.panel_id = nil
1166         r = @story.allow?
1167         r.should be_false
1168       end
1169       it 'falseを返す' do
1170         Panel.any_instance.stub(:usable?).with(any_args).and_return(false)
1171         r = @story.allow?
1172         r.should be_false
1173       end
1174     end
1175   end
1176   describe '保存に於いて' do
1177     before do
1178       @comic = FactoryGirl.create :comic, :author_id => @author.id
1179       @panel = FactoryGirl.create :panel, :author_id => @author.id
1180       @story = FactoryGirl.build :story, :t => nil, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1181     end
1182     context 'つつがなく終わるとき' do
1183       it '編集許可チェックを依頼している' do
1184         Story.any_instance.stub(:allow?).with(any_args).and_return(true)
1185         Story.any_instance.should_receive(:allow?).with(any_args).exactly(1)
1186         r = @story.store
1187       end
1188       it '順序入れ替えを依頼している' do
1189         Story.any_instance.stub(:rotate).with(any_args).and_return(0)
1190         Story.any_instance.should_receive(:rotate).with(any_args).exactly(1)
1191         Story.any_instance.stub(:save).with(any_args).and_return(true)
1192         Story.stub(:validate_t).with(any_args).and_return(true)
1193         r = @story.store 
1194       end
1195       it '保存を依頼している' do
1196         Story.stub(:new_t).with(any_args).and_return(0)
1197         Story.any_instance.stub(:save).with(any_args).and_return(true)
1198         Story.any_instance.should_receive(:save).with(any_args).exactly(1)
1199         Story.stub(:validate_t).with(any_args).and_return(true)
1200         r = @story.store
1201       end
1202       it 'tのシリアライズチェックを依頼している' do
1203         Story.stub(:new_t).with(any_args).and_return(0)
1204         Story.any_instance.stub(:save).with(any_args).and_return(true)
1205         Story.stub(:validate_t).with(any_args).and_return(true)
1206         Story.should_receive(:validate_t).with(any_args).exactly(1)
1207         r = @story.store
1208       end
1209     end
1210     #入れ替えテストと同じテストを実施。こちらはシフトだけでなく本尊も更新されている
1211     context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で2に挿入したとき' do
1212       before do
1213         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
1214         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
1215         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1216         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1217         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1218         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1219         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1220         @story6 = FactoryGirl.build :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1221       end
1222       it '既存のt0には変化がない' do
1223         @story6.store
1224         @story.reload
1225         @story.t.should eq 0
1226       end
1227       it '既存のt1には変化がない' do
1228         @story6.store
1229         @story2.reload
1230         @story2.t.should eq 1
1231       end
1232       it '既存のt2を3にシフトしている' do
1233         @story6.store
1234         @story3.reload
1235         @story3.t.should eq 3
1236       end
1237       it '既存のt3を4にシフトしている' do
1238         @story6.store
1239         @story4.reload
1240         @story4.t.should eq 4
1241       end
1242       it '既存のt5を5にシフトしている' do
1243         @story6.store
1244         @story5.reload
1245         @story5.t.should eq 5
1246       end
1247       it '新規のt2が作成されている' do
1248         @story6.store
1249         @story6.reload
1250         @story6.t.should eq 2
1251       end
1252       it '他のコミックに影響がない' do
1253         @ot = @storyc2.t
1254         @story6.store
1255         @storyc2.reload
1256         @storyc2.t.should eq @ot
1257       end
1258     end
1259     context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で3を1に移動したとき' do
1260       before do
1261         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
1262         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
1263         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1264         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1265         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1266         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1267         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1268         @ot = @story4.t
1269         @story4.t = 1
1270       end
1271       it '既存のt0には変化がない' do
1272         @story4.store @ot
1273         @story.reload
1274         @story.t.should eq 0
1275       end
1276       it '既存のt4には変化がない' do
1277         @story4.store @ot
1278         @story5.reload
1279         @story5.t.should eq 4
1280       end
1281       it '既存のt1を2にシフトしている' do
1282         @story4.store @ot
1283         @story2.reload
1284         @story2.t.should eq 2
1285       end
1286       it '既存のt2を3にシフトしている' do
1287         @story4.store @ot
1288         @story3.reload
1289         @story3.t.should eq 3
1290       end
1291       it '既存のt3を1にシフトしている' do
1292         @story4.store @ot
1293         @story4.reload
1294         @story4.t.should eq 1
1295       end
1296       it '他のコミックに影響がない' do
1297         @story4.store @ot
1298         @storyc2.reload
1299         @storyc2.t.should eq 0
1300       end
1301     end
1302     context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で1を3に移動したとき' do
1303       before do
1304         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
1305         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
1306         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1307         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1308         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1309         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1310         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1311         @ot = @story2.t
1312         @story2.t = 3
1313       end
1314       it '既存のt0には変化がない' do
1315         @story2.store @ot
1316         @story.reload
1317         @story.t.should eq 0
1318       end
1319       it '既存のt4には変化がない' do
1320         @story2.store @ot
1321         @story5.reload
1322         @story5.t.should eq 4
1323       end
1324       it '既存のt1を3にシフトしている' do
1325         @story2.store @ot
1326         @story2.reload
1327         @story2.t.should eq 3
1328       end
1329       it '既存のt2を1にシフトしている' do
1330         @story2.store @ot
1331         @story3.reload
1332         @story3.t.should eq 1
1333       end
1334       it '既存のt3を2にシフトしている' do
1335         @story2.store @ot
1336         @story4.reload
1337         @story4.t.should eq 2
1338       end
1339       it '他のコミックに影響がない' do
1340         @story2.store @ot
1341         @storyc2.reload
1342         @storyc2.t.should eq 0
1343       end
1344     end
1345     #ロールバックテスト。入れ替えが直接DBをいじるので、すべてのケースで確実にロールバックを確認する
1346     context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で2に挿入したが保存に失敗したとき' do
1347       before do
1348         Story.any_instance.stub(:save).with(any_args).and_return(false)
1349         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
1350         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
1351         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1352         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1353         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1354         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1355         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1356         @story6 = FactoryGirl.build :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1357       end
1358       it '既存のtに変化がない' do
1359         @story6.store
1360         @story.reload
1361         @story.t.should eq 0
1362         @story2.reload
1363         @story2.t.should eq 1
1364         @story3.reload
1365         @story3.t.should eq 2
1366         @story4.reload
1367         @story4.t.should eq 3
1368         @story5.reload
1369         @story5.t.should eq 4
1370         @storyc2.reload
1371         @storyc2.t.should eq 0
1372       end
1373       it 'falseを返す' do
1374         r = @story6.store
1375         r.should be_false
1376       end
1377     end
1378     context 'テーブルに5件(t:0,1,2,3,4)+他のコミック1件で3を1に移動したがシリアルチェックに失敗したとき' do
1379       before do
1380         Story.stub(:validate_t).with(any_args).and_return(false)
1381         @comic2 = FactoryGirl.create :comic, :author_id => @author.id
1382         @storyc2 = FactoryGirl.create :story, :t => 0, :comic_id => @comic2.id, :panel_id => @panel.id, :author_id => @author.id
1383         @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1384         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1385         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1386         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1387         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1388         @ot = @story4.t
1389         @story4.t = 1
1390       end
1391       it '既存のtに変化がない' do
1392         @story4.store @ot
1393         @story.reload
1394         @story.t.should eq 0
1395         @story2.reload
1396         @story2.t.should eq 1
1397         @story3.reload
1398         @story3.t.should eq 2
1399         @story4.reload
1400         @story4.t.should eq 3
1401         @story5.reload
1402         @story5.t.should eq 4
1403         @storyc2.reload
1404         @storyc2.t.should eq 0
1405       end
1406       it 'falseを返す' do
1407         r = @story4.store @ot
1408         r.should be_false
1409       end
1410       it 'tにエラーメッセージが入っている' do
1411         @story4.store @ot
1412         @story4.errors[:t].should_not be_empty
1413         @story4.valid?.should be_true
1414       end
1415     end
1416     context '編集不可だったとき' do
1417       before do
1418         @story = FactoryGirl.build :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1419         Story.any_instance.stub(:allow?).and_return(false)
1420       end
1421       it '403Forbidden例外を返す' do
1422         lambda{
1423           @story.store
1424         }.should raise_error(ActiveRecord::Forbidden)
1425       end
1426     end
1427   end
1428   describe '切り詰め処理つき削除に於いて' do
1429     before do
1430       @comic = FactoryGirl.create :comic, :author_id => @author.id
1431       @panel = FactoryGirl.create :panel, :author_id => @author.id
1432       @story = FactoryGirl.create :story, :t => 0, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1433     end
1434     context 'つつがなく終わるとき' do
1435       it '削除される' do
1436         lambda{
1437           @story.destroy_and_shorten
1438         }.should change(Story, :count ).by(-1)
1439       end
1440     end
1441     #連携テスト。切り詰めが直接DBをいじる
1442     context '2件で先頭を削除したとき' do
1443       before do
1444         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1445       end
1446       it '行が削除される' do
1447         lambda{
1448           @story.destroy_and_shorten
1449         }.should change(Story, :count ).by(-1)
1450       end
1451       it '先頭は削除される' do
1452         @story.destroy_and_shorten
1453         lambda{
1454           Story.find @story.id
1455         }.should raise_error(ActiveRecord::RecordNotFound)
1456       end
1457       it '2件目は前に詰められる' do
1458         @story.destroy_and_shorten
1459         @story2.reload
1460         @story2.t.should eq 0
1461       end
1462     end
1463     context '3件で先頭を削除したとき' do
1464       before do
1465         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1466         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1467       end
1468       it '行が削除される' do
1469         lambda{
1470           @story.destroy_and_shorten
1471         }.should change(Story, :count ).by(-1)
1472       end
1473       it '先頭は削除される' do
1474         @story.destroy_and_shorten
1475         lambda{
1476           Story.find @story.id
1477         }.should raise_error(ActiveRecord::RecordNotFound)
1478       end
1479       it '2件目は前に詰められる' do
1480         @story.destroy_and_shorten
1481         @story2.reload
1482         @story2.t.should eq 0
1483       end
1484       it '3件目は前に詰められる' do
1485         @story.destroy_and_shorten
1486         @story3.reload
1487         @story3.t.should eq 1
1488       end
1489     end
1490     context '5件で3件目を削除したとき' do
1491       before do
1492         @story2 = FactoryGirl.create :story, :t => 1, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1493         @story3 = FactoryGirl.create :story, :t => 2, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1494         @story4 = FactoryGirl.create :story, :t => 3, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1495         @story5 = FactoryGirl.create :story, :t => 4, :comic_id => @comic.id, :panel_id => @panel.id, :author_id => @author.id
1496       end
1497       it '行が削除される' do
1498         lambda{
1499           @story3.destroy_and_shorten
1500         }.should change(Story, :count ).by(-1)
1501       end
1502       it '1件目は変化がない' do
1503         @story3.destroy_and_shorten
1504         @story.reload
1505         @story.t.should eq 0
1506       end
1507       it '2件目は変化がない' do
1508         @story3.destroy_and_shorten
1509         @story2.reload
1510         @story2.t.should eq 1
1511       end
1512       it '3件目は削除される' do
1513         @story3.destroy_and_shorten
1514         lambda{
1515           Story.find @story3.id
1516         }.should raise_error(ActiveRecord::RecordNotFound)
1517       end
1518       it '4件目は前に詰められる' do
1519         @story3.destroy_and_shorten
1520         @story4.reload
1521         @story4.t.should eq 2
1522       end
1523       it '5件目は前に詰められる' do
1524         @story3.destroy_and_shorten
1525         @story5.reload
1526         @story5.t.should eq 3
1527       end
1528     end
1529     #ロールバックテスト。切り詰めが直接DBをいじるので、すべてのケースで確実にロールバックを確認する
1530   end
1531 end