OSDN Git Service

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