OSDN Git Service

t#31521:fix story pager
[pettanr/pettanr.git] / spec / models / speech_balloon_spec.rb
1 # -*- encoding: utf-8 -*-
2 require 'spec_helper'
3 #フキダシ
4
5 describe SpeechBalloon do
6   before do
7     @admin = FactoryGirl.create :admin
8     @user = FactoryGirl.create( :user_yas)
9     @author = FactoryGirl.create :author, :user_id => @user.id
10     @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
11     @other_user = FactoryGirl.create( :user_yas)
12     @other_author = FactoryGirl.create :author, :user_id => @other_user.id
13     @other_artist = FactoryGirl.create :artist_yas, :author_id => @other_author.id
14     @sp = FactoryGirl.create :system_picture
15     @lg = FactoryGirl.create :license_group
16     @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
17     
18     @panel = FactoryGirl.create :panel, :author_id => @author.id
19     @writing_format = FactoryGirl.create :writing_format
20     @speech_balloon_template = FactoryGirl.create :speech_balloon_template, "name" => "circle@pettan.com", "classname" => "CircleSpeechBalloon", "caption" => "cc",  "system_picture_id" => @sp.id, "settings" => '{}'
21   end
22   
23   describe '検証に於いて' do
24     before do
25       @sb = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id
26       @speech = @sb.build_speech(
27         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
28       )
29       @balloon = @sb.build_balloon(
30         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
31       )
32       @sb.boost
33       @sb.save!
34     end
35     
36     context 'オーソドックスなデータのとき' do
37       it '下限データが通る' do
38         @sb.classname = 'a'
39         @sb.z = 1
40         @sb.t = 0
41         @sb.should be_valid
42       end
43       it '上限データが通る' do
44         @sb.classname = 'a'*50
45         @sb.z = 99999
46         @sb.t = 99999
47         @sb.should be_valid
48       end
49     end
50     
51     context 'panel_idを検証するとき' do
52       #ネストの保存はnilを許可しなければならないので数値チェックだけ
53       it '数値でなければ失敗する' do
54         @sb.panel_id = 'a'
55         @sb.should_not be_valid
56       end
57     end
58     context 'speech_balloon_template_idを検証するとき' do
59       it 'nullなら失敗する' do
60         @sb.speech_balloon_template_id = nil
61         @sb.should_not be_valid
62       end
63       it '数値でなければ失敗する' do
64         @sb.speech_balloon_template_id = 'a'
65         @sb.should_not be_valid
66       end
67       it '存在するフキダシテンプレートでなければ失敗する' do
68         @sb.speech_balloon_template_id = 0
69         @sb.should_not be_valid
70       end
71     end
72     context 'classnameを検証するとき' do
73       it 'nullなら失敗する' do
74         @sb.classname = ''
75         @sb.should_not be_valid
76       end
77       it '51文字以上なら失敗する' do
78         @sb.classname = 'a'*51
79         @sb.should_not be_valid
80       end
81     end
82     context 'tを検証するとき' do
83       it 'nullなら失敗する' do
84         @sb.t = nil
85         @sb.should_not be_valid
86       end
87       it '数値でなければ失敗する' do
88         @sb.t = 'a'
89         @sb.should_not be_valid
90       end
91       it '負なら失敗する' do
92         @sb.t = -1
93         @sb.should_not be_valid
94       end
95     end
96     context 'settingsを検証するとき' do
97     end
98   end
99   
100   describe '文字コード検証に於いて' do
101     before do
102       @sb = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id
103     end
104     
105     context 'classnameを検証するとき' do
106       it 'Shift JISなら失敗する' do
107         @sb.classname = "\x83G\x83r\x83]\x83D"
108         lambda{
109           @sb.valid_encode
110         }.should raise_error(Pettanr::BadRequest)
111       end
112     end
113     
114     context 'settingsを検証するとき' do
115       it 'Shift JISなら失敗する' do
116         @sb.settings = "\x83G\x83r\x83]\x83D"
117         lambda{
118           @sb.valid_encode
119         }.should raise_error(Pettanr::BadRequest)
120       end
121     end
122     
123     context 'captionを検証するとき' do
124       it 'Shift JISなら失敗する' do
125         @sb.caption = "\x83G\x83r\x83]\x83D"
126         lambda{
127           @sb.valid_encode
128         }.should raise_error(Pettanr::BadRequest)
129       end
130     end
131     
132   end
133   
134   describe '閲覧許可に於いて' do
135     before do
136       @sb = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id
137       @speech = @sb.build_speech(
138         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
139       )
140       @balloon = @sb.build_balloon(
141         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
142       )
143       @sb.boost
144       @sb.save!
145     end
146     context 'オープンモードのとき' do
147       before do
148         MagicNumber['run_mode'] = 0
149       end
150       it '自身にゲスト用ロールチェックを問い合わせしている' do
151         SpeechBalloon.any_instance.stub(:guest_role_check).and_return(true)
152         SpeechBalloon.any_instance.should_receive(:guest_role_check).with(any_args).exactly(1)
153         r = @sb.visible?([@author])
154       end
155       it 'ゲスト用ロールチェックが失敗したとき、falseを返す' do
156         SpeechBalloon.any_instance.stub(:guest_role_check).and_return(false)
157         r = @sb.visible?([@author])
158         r.should be_false
159       end
160     end
161     context 'クローズドモードのとき' do
162       before do
163         MagicNumber['run_mode'] = 1
164       end
165       it '自身に読者用ロールチェックを問い合わせしている' do
166         SpeechBalloon.any_instance.stub(:reader_role_check).and_return(true)
167         SpeechBalloon.any_instance.should_receive(:reader_role_check).with(any_args).exactly(1)
168         r = @sb.visible?([@author])
169       end
170       it '読者用ロールチェックが失敗したとき、falseを返す' do
171         SpeechBalloon.any_instance.stub(:reader_role_check).and_return(false)
172         r = @sb.visible?([@author])
173         r.should be_false
174       end
175     end
176     context '事前チェックする' do
177       before do
178         MagicNumber['run_mode'] = 1
179         SpeechBalloon.any_instance.stub(:reader_role_check).and_return(true)
180       end
181       it '自身のコマに所持判定を問い合わせしている' do
182         Panel.any_instance.stub(:own?).and_return(true)
183         Panel.any_instance.should_receive(:own?).with(any_args).exactly(1)
184         r = @sb.visible?([@author])
185       end
186       it '自身のコマに閲覧許可を問い合わせしている' do
187         Panel.any_instance.stub(:own?).and_return(false)
188         Panel.any_instance.stub(:visible?).and_return(true)
189         Panel.any_instance.should_receive(:visible?).with(any_args).exactly(1)
190         r = @sb.visible?([@author])
191       end
192     end
193     context 'つつがなく終わるとき' do
194       before do
195         MagicNumber['run_mode'] = 1
196         Panel.any_instance.stub(:reader_role_check).and_return(true)
197       end
198       it '自分のコマのフキダシなら許可する' do
199         Panel.any_instance.stub(:own?).and_return(true)
200         Panel.any_instance.stub(:visible?).and_return(false)
201         r = @sb.visible?([@author])
202         r.should be_true
203       end
204       it '他人の非公開コマのフキダシなら許可しない' do
205         Panel.any_instance.stub(:own?).and_return(false)
206         Panel.any_instance.stub(:visible?).and_return(false)
207         r = @sb.visible?([@author])
208         r.should be_false
209       end
210       it '他人のコマのフキダシでも公開なら許可する' do
211         Panel.any_instance.stub(:own?).and_return(false)
212         Panel.any_instance.stub(:visible?).and_return(true)
213         r = @sb.visible?([@author])
214         r.should be_true
215       end
216     end
217   end
218   
219   describe '一覧取得に於いて' do
220     before do
221       @sb = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id
222       @speech = @sb.build_speech(
223         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
224       )
225       @balloon = @sb.build_balloon(
226         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
227       )
228       @sb.boost
229       @sb.save!
230     end
231     context 'page補正について' do
232       it '文字列から数値に変換される' do
233         SpeechBalloon.page('8').should eq 8
234       end
235       it 'nilの場合は1になる' do
236         SpeechBalloon.page().should eq 1
237       end
238       it '0以下の場合は1になる' do
239         SpeechBalloon.page('0').should eq 1
240       end
241     end
242     context 'page_size補正について' do
243       it '文字列から数値に変換される' do
244         SpeechBalloon.page_size('7').should eq 7
245       end
246       it 'nilの場合はSpeechBalloon.default_page_sizeになる' do
247         SpeechBalloon.page_size().should eq SpeechBalloon.default_page_size
248       end
249       it '0以下の場合はSpeechBalloon.default_page_sizeになる' do
250         SpeechBalloon.page_size('0').should eq SpeechBalloon.default_page_size
251       end
252       it 'SpeechBalloon.max_page_sizeを超えた場合はSpeechBalloon.max_page_sizeになる' do
253         SpeechBalloon.page_size('1000').should eq SpeechBalloon.max_page_size
254       end
255     end
256     context 'つつがなく終わるとき' do
257       it '一覧取得オプションを利用している' do
258         SpeechBalloon.stub(:list_opt).with(any_args).and_return({:include => :panel})
259         SpeechBalloon.should_receive(:list_opt).with(any_args).exactly(1)
260         r = SpeechBalloon.list
261       end
262     end
263     it 'リストを返す' do
264       r = SpeechBalloon.list
265       r.should eq [@sb]
266     end
267     it '時系列で並んでいる' do
268       #公開されたコマのフキダシは(他人のフキダシであっても)含んでいる
269       hc = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1
270       npl = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
271       npl.build_speech(
272         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
273       )
274       npl.build_balloon(
275         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
276       )
277       npl.boost
278       npl.save!
279       r = SpeechBalloon.list
280       r.should eq [npl, @sb]
281     end
282     it '非公開のコマのフキダシは自分のフキダシであっても含まない' do
283       hc = FactoryGirl.create :panel, :author_id => @author.id, :publish => 0
284       npl = FactoryGirl.build :speech_balloon, :panel_id => hc.id, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
285       npl.build_speech(
286         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
287       )
288       npl.build_balloon(
289         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
290       )
291       npl.boost
292       npl.save!
293       pl = SpeechBalloon.list
294       pl.should eq [@sb]
295     end
296     context 'DBに5件あって1ページの件数を2件に変えたとして' do
297       before do
298         @sb2 = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :t => 1, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
299         @speech2 = @sb2.build_speech(
300           FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
301         )
302         @balloon2 = @sb2.build_balloon(
303           FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id, :updated_at => Time.now + 100)
304         )
305         @sb2.boost
306         @sb2.save!
307         @sb3 = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :t => 2, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 200
308         @speech3 = @sb3.build_speech(
309           FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
310         )
311         @balloon3 = @sb3.build_balloon(
312           FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id, :updated_at => Time.now + 200)
313         )
314         @sb3.boost
315         @sb3.save!
316         @sb4 = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :t => 3, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 300
317         @speech4 = @sb4.build_speech(
318           FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
319         )
320         @balloon4 = @sb4.build_balloon(
321           FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id, :updated_at => Time.now + 300)
322         )
323         @sb4.boost
324         @sb4.save!
325         @sb5 = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :t => 4, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 400
326         @speech5 = @sb5.build_speech(
327           FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
328         )
329         @balloon5 = @sb5.build_balloon(
330           FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id, :updated_at => Time.now + 400)
331         )
332         @sb5.boost
333         @sb5.save!
334         SpeechBalloon.stub(:default_page_size).and_return(2)
335       end
336       it '通常は2件を返す' do
337         pl = SpeechBalloon.list
338         pl.should have(2).items 
339       end
340       it 'page=1なら末尾2件を返す' do
341         #時系列で並んでいる
342         pl = SpeechBalloon.list(1)
343         pl.should eq [@sb5, @sb4]
344       end
345       it 'page=2なら中間2件を返す' do
346         pl = SpeechBalloon.list(2)
347         pl.should eq [@sb3, @sb2]
348       end
349       it 'page=3なら先頭1件を返す' do
350         pl = SpeechBalloon.list(3)
351         pl.should eq [@sb]
352       end
353     end
354   end
355   
356   describe '自分のフキダシ一覧取得に於いて' do
357     before do
358       @sb = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id
359       @speech = @sb.build_speech(
360         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
361       )
362       @balloon = @sb.build_balloon(
363         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
364       )
365       @sb.boost
366       @sb.save!
367     end
368     context 'つつがなく終わるとき' do
369       it '一覧取得オプションを利用している' do
370         SpeechBalloon.stub(:list_opt).with(any_args).and_return({:include => :panel})
371         SpeechBalloon.should_receive(:list_opt).with(any_args).exactly(1)
372         r = SpeechBalloon.mylist @author
373       end
374     end
375     it 'リストを返す' do
376       pl = SpeechBalloon.mylist @author
377       pl.should eq [@sb]
378     end
379     it '時系列で並んでいる' do
380       nsb = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :t => 1, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
381       nsb.build_speech(
382         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
383       )
384       nsb.build_balloon(
385         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
386       )
387       nsb.boost
388       nsb.save!
389       pl = SpeechBalloon.mylist @author
390       pl.should eq [nsb, @sb]
391     end
392     it '他人のコマのフキダシは公開コマでも含まない' do
393       hpl = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1
394       nsb = FactoryGirl.build :speech_balloon, :panel_id => hpl.id, :t => 1, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
395       nsb.build_speech(
396         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
397       )
398       nsb.build_balloon(
399         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
400       )
401       nsb.boost
402       nsb.save!
403       pl = SpeechBalloon.mylist @author
404       pl.should eq [@sb]
405     end
406     it '自分のコマのフキダシは非公開コマでも含んでいる' do
407       pl = FactoryGirl.create :panel, :author_id => @author.id, :publish => 0
408       nsb = FactoryGirl.build :speech_balloon, :panel_id => pl.id, :t => 1, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
409       nsb.build_speech(
410         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
411       )
412       nsb.build_balloon(
413         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
414       )
415       nsb.boost
416       nsb.save!
417       r = SpeechBalloon.mylist @author
418       r.should eq [nsb, @sb]
419     end
420     context 'DBに5件あって1ページの件数を2件に変えたとして' do
421       before do
422         @sb2 = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :t => 1, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
423         @speech2 = @sb2.build_speech(
424           FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
425         )
426         @balloon2 = @sb2.build_balloon(
427           FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id, :updated_at => Time.now + 100)
428         )
429         @sb2.boost
430         @sb2.save!
431         @sb3 = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :t => 2, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 200
432         @speech3 = @sb3.build_speech(
433           FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
434         )
435         @balloon3 = @sb3.build_balloon(
436           FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id, :updated_at => Time.now + 200)
437         )
438         @sb3.boost
439         @sb3.save!
440         @sb4 = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :t => 3, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 300
441         @speech4 = @sb4.build_speech(
442           FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
443         )
444         @balloon4 = @sb4.build_balloon(
445           FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id, :updated_at => Time.now + 300)
446         )
447         @sb4.boost
448         @sb4.save!
449         @sb5 = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :t => 4, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 400
450         @speech5 = @sb5.build_speech(
451           FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
452         )
453         @balloon5 = @sb5.build_balloon(
454           FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id, :updated_at => Time.now + 400)
455         )
456         @sb5.boost
457         @sb5.save!
458       end
459       it '通常は2件を返す' do
460         r = SpeechBalloon.mylist @author, 1, 2
461         r.should have(2).items 
462       end
463       it 'page=1なら末尾2件を返す' do
464         #時系列で並んでいる
465         r = SpeechBalloon.mylist(@author, 1, 2)
466         r.should eq [@sb5, @sb4]
467       end
468       it 'page=2なら中間2件を返す' do
469         r = SpeechBalloon.mylist(@author, 2, 2)
470         r.should eq [@sb3, @sb2]
471       end
472       it 'page=3なら先頭1件を返す' do
473         r = SpeechBalloon.mylist(@author, 3, 2)
474         r.should eq [@sb]
475       end
476     end
477   end
478   
479   describe '他作家のフキダシ一覧取得に於いて' do
480     before do
481       @sb = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id
482       @speech = @sb.build_speech(
483         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
484       )
485       @balloon = @sb.build_balloon(
486         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
487       )
488       @sb.boost
489       @sb.save!
490       @other_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 1
491       @other_sb = FactoryGirl.build :speech_balloon, :panel_id => @other_panel.id, :speech_balloon_template_id => @speech_balloon_template.id
492       @other_speech = @other_sb.build_speech(
493         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
494       )
495       @other_balloon = @other_sb.build_balloon(
496         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
497       )
498       @other_sb.boost
499       @other_sb.save!
500     end
501     it 'リストを返す' do
502       r = SpeechBalloon.himlist @other_author
503       r.should eq [@other_sb]
504     end
505     it '時系列で並んでいる' do
506       new_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :updated_at => Time.now + 100
507       new_sb = FactoryGirl.build :speech_balloon, :panel_id => new_panel.id, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
508       new_sb.build_speech(
509         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
510       )
511       new_sb.build_balloon(
512         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
513       )
514       new_sb.boost
515       new_sb.save!
516       r = SpeechBalloon.himlist @other_author
517       r.should eq [new_sb, @other_sb]
518     end
519     it '公開コマに限る' do
520       hidden_panel = FactoryGirl.create :panel, :author_id => @other_author.id, :publish => 0
521       hidden_sb = FactoryGirl.build :speech_balloon, :panel_id => hidden_panel.id, :speech_balloon_template_id => @speech_balloon_template.id, :updated_at => Time.now + 100
522       hidden_sb.build_speech(
523         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
524       )
525       hidden_sb.build_balloon(
526         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
527       )
528       hidden_sb.boost
529       hidden_sb.save!
530       r = SpeechBalloon.himlist @other_author
531       r.should eq [@other_sb]
532     end
533     context 'DBに5件あって1ページの件数を2件に変えたとして' do
534       before do
535         @other_sb2 = FactoryGirl.build :speech_balloon, :panel_id => @other_panel.id, :t => 1, :speech_balloon_template_id => @speech_balloon_template.id
536         @other_sb2.build_speech(
537           FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
538         )
539         @other_sb2.build_balloon(
540           FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id, :updated_at => Time.now + 100)
541         )
542         @other_sb2.boost
543         @other_sb2.save!
544         @other_sb3 = FactoryGirl.build :speech_balloon, :panel_id => @other_panel.id, :t => 2, :speech_balloon_template_id => @speech_balloon_template.id
545         @other_sb3.build_speech(
546           FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
547         )
548         @other_sb3.build_balloon(
549           FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id, :updated_at => Time.now + 200)
550         )
551         @other_sb3.boost
552         @other_sb3.save!
553         @other_sb4 = FactoryGirl.build :speech_balloon, :panel_id => @other_panel.id, :t => 3, :speech_balloon_template_id => @speech_balloon_template.id
554         @other_sb4.build_speech(
555           FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
556         )
557         @other_sb4.build_balloon(
558           FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id, :updated_at => Time.now + 300)
559         )
560         @other_sb4.boost
561         @other_sb4.save!
562         @other_sb5 = FactoryGirl.build :speech_balloon, :panel_id => @other_panel.id, :t => 4, :speech_balloon_template_id => @speech_balloon_template.id
563         @other_sb5.build_speech(
564           FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
565         )
566         @other_sb5.build_balloon(
567           FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id, :updated_at => Time.now + 400)
568         )
569         @other_sb5.boost
570         @other_sb5.save!
571       end
572       it '通常は2件を返す' do
573         r = SpeechBalloon.himlist @other_author, 1, 2
574         r.should have(2).items 
575       end
576       it 'page=1なら末尾2件を返す' do
577         #時系列で並んでいる
578         r = SpeechBalloon.himlist @other_author, 1, 2
579         r.should eq [@other_sb5, @other_sb4]
580       end
581       it 'page=2なら中間2件を返す' do
582         r = SpeechBalloon.himlist @other_author, 2, 2
583         r.should eq [@other_sb3, @other_sb2]
584       end
585       it 'page=3なら先頭1件を返す' do
586         r = SpeechBalloon.himlist @other_author, 3, 2
587         r.should eq [@other_sb]
588       end
589     end
590   end
591   
592   describe 'フキダシ一覧ページ制御に於いて' do
593     before do
594       SpeechBalloon.stub(:count).with(any_args).and_return(100)
595     end
596     it 'ページ制御を返す' do
597       r = SpeechBalloon.list_paginate 
598       r.is_a?(Kaminari::PaginatableArray).should be_true
599     end
600     it 'フキダシ一覧の取得条件を利用している' do
601       SpeechBalloon.stub(:list_where).with(any_args).and_return('')
602       SpeechBalloon.should_receive(:list_where).with(any_args).exactly(1)
603       r = SpeechBalloon.list_paginate 
604     end
605     it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do
606       r = SpeechBalloon.list_paginate 3, 10
607       r.limit_value.should eq 10
608       r.offset_value.should eq 20
609     end
610   end
611   
612   describe '自分のフキダシ一覧ページ制御に於いて' do
613     before do
614       SpeechBalloon.stub(:count).with(any_args).and_return(100)
615     end
616     it 'ページ制御を返す' do
617       r = SpeechBalloon.mylist_paginate @author
618       r.is_a?(Kaminari::PaginatableArray).should be_true
619     end
620     it '自分のフキダシ一覧の取得条件を利用している' do
621       SpeechBalloon.stub(:mylist_where).with(any_args).and_return('')
622       SpeechBalloon.should_receive(:mylist_where).with(any_args).exactly(1)
623       r = SpeechBalloon.mylist_paginate @author
624     end
625     it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do
626       r = SpeechBalloon.mylist_paginate @author, 3, 10
627       r.limit_value.should eq 10
628       r.offset_value.should eq 20
629     end
630   end
631   
632   describe '他作家のフキダシ一覧ページ制御に於いて' do
633     before do
634       SpeechBalloon.stub(:count).with(any_args).and_return(100)
635     end
636     it 'ページ制御を返す' do
637       r = SpeechBalloon.himlist_paginate @other_author
638       r.is_a?(Kaminari::PaginatableArray).should be_true
639     end
640     it '他作家のフキダシ一覧の取得条件を利用している' do
641       SpeechBalloon.stub(:himlist_where).with(any_args).and_return('')
642       SpeechBalloon.should_receive(:himlist_where).with(any_args).exactly(1)
643       r = SpeechBalloon.himlist_paginate @other_author
644     end
645     it 'ページ件数10のとき、3ページ目のオフセットは20から始まる' do
646       r = SpeechBalloon.himlist_paginate @other_author, 3, 10
647       r.limit_value.should eq 10
648       r.offset_value.should eq 20
649     end
650   end
651   
652   describe '一覧取得オプションに於いて' do
653     it '4つの項目を含んでいる' do
654       r = SpeechBalloon.list_opt
655       r.should have(4).items
656     end
657     it 'コマを含んでいる' do
658       r = SpeechBalloon.list_opt
659       r.has_key?(:panel).should be_true
660     end
661       it 'コマは作家を含んでいる' do
662         r = SpeechBalloon.list_opt
663         r[:panel].has_key?(:author).should be_true
664       end
665     it 'フキダシ枠を含んでいる' do
666       r = SpeechBalloon.list_opt
667       r.has_key?(:balloon).should be_true
668     end
669     it 'セリフを含んでいる' do
670       r = SpeechBalloon.list_opt
671       r.has_key?(:speech).should be_true
672     end
673     it 'フキダシテンプレートを含んでいる' do
674       r = SpeechBalloon.list_opt
675       r.has_key?(:speech_balloon_template).should be_true
676     end
677   end
678   describe 'json一覧出力オプションに於いて' do
679     before do
680       @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1
681       @sb = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id
682       @speech = @sb.build_speech(
683         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
684       )
685       @balloon = @sb.build_balloon(
686         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
687       )
688       @sb.boost
689       @sb.save!
690     end
691     it 'コマを含んでいる' do
692       r = SpeechBalloon.list.to_json SpeechBalloon.list_json_opt
693       j = JSON.parse r
694       i = j.first
695       i.has_key?('panel').should be_true
696     end
697       it 'コマは作家を含んでいる' do
698         r = SpeechBalloon.list.to_json SpeechBalloon.list_json_opt
699         j = JSON.parse r
700         i = j.first
701         s = i['panel']
702         s.has_key?('author').should be_true
703       end
704     it 'フキダシ枠を含んでいる' do
705       r = SpeechBalloon.list.to_json SpeechBalloon.list_json_opt
706       j = JSON.parse r
707       i = j.first
708       i.has_key?('balloon').should be_true
709     end
710     it 'セリフを含んでいる' do
711       r = SpeechBalloon.list.to_json SpeechBalloon.list_json_opt
712       j = JSON.parse r
713       i = j.first
714       i.has_key?('speech').should be_true
715     end
716     it 'フキダシテンプレートを含んでいる' do
717       r = SpeechBalloon.list.to_json SpeechBalloon.list_json_opt
718       j = JSON.parse r
719       i = j.first
720       i.has_key?('speech_balloon_template').should be_true
721     end
722   end
723   
724   describe '単体取得に於いて' do
725     before do
726       @sb = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id
727       @speech = @sb.build_speech(
728         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
729       )
730       @balloon = @sb.build_balloon(
731         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
732       )
733       @sb.boost
734       @sb.save!
735     end
736     context 'つつがなく終わるとき' do
737       it '単体取得オプションを利用している' do
738         SpeechBalloon.stub(:show_opt).with(any_args).and_return({:include => :panel})
739         SpeechBalloon.should_receive(:show_opt).with(any_args).exactly(1)
740         r = SpeechBalloon.show @sb.id, @author
741       end
742       it '閲覧許可を問い合わせている' do
743         SpeechBalloon.any_instance.stub(:visible?).with(any_args).and_return(true)
744         SpeechBalloon.any_instance.should_receive(:visible?).with(any_args).exactly(1)
745         r = SpeechBalloon.show @sb.id, @author
746       end
747     end
748     it '指定のフキダシを返す' do
749       SpeechBalloon.any_instance.stub(:visible?).and_return(true)
750       pl = SpeechBalloon.show @sb.id, @author
751       pl.should eq @sb
752     end
753     context '閲覧許可が出なかったとき' do
754       it '403Forbidden例外を返す' do
755         SpeechBalloon.any_instance.stub(:visible?).and_return(false)
756         lambda{
757           SpeechBalloon.show @sb.id, @author
758         }.should raise_error(ActiveRecord::Forbidden)
759       end
760     end
761     context '存在しないフキダシを開こうとしたとき' do
762       it '404RecordNotFound例外を返す' do
763         lambda{
764           SpeechBalloon.show 110, @author
765         }.should raise_error(ActiveRecord::RecordNotFound)
766       end
767     end
768   end
769   describe '単体取得オプションに於いて' do
770     it 'includeキーを含んでいる' do
771       r = SpeechBalloon.show_opt
772       r.has_key?(:include).should be_true
773     end
774     it '4つの項目を含んでいる' do
775       r = SpeechBalloon.show_opt[:include]
776       r.should have(4).items
777     end
778     it 'コマを含んでいる' do
779       r = SpeechBalloon.show_opt[:include]
780       r.has_key?(:panel).should be_true
781     end
782       it 'コマは作家を含んでいる' do
783         r = SpeechBalloon.show_opt[:include]
784         r[:panel].has_key?(:author).should be_true
785       end
786     it 'フキダシ枠を含んでいる' do
787       r = SpeechBalloon.show_opt[:include]
788       r.has_key?(:balloon).should be_true
789     end
790     it 'セリフを含んでいる' do
791       r = SpeechBalloon.show_opt[:include]
792       r.has_key?(:speech).should be_true
793     end
794     it 'フキダシテンプレートを含んでいる' do
795       r = SpeechBalloon.show_opt[:include]
796       r.has_key?(:speech_balloon_template).should be_true
797     end
798   end
799   describe 'json単体出力オプションに於いて' do
800     before do
801       @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1
802       @sb = FactoryGirl.build :speech_balloon, :panel_id => @panel.id, :speech_balloon_template_id => @speech_balloon_template.id
803       @speech = @sb.build_speech(
804         FactoryGirl.attributes_for(:speech, :writing_format_id => @writing_format.id)
805       )
806       @balloon = @sb.build_balloon(
807         FactoryGirl.attributes_for(:balloon, :system_picture_id => @sp.id)
808       )
809       @sb.boost
810       @sb.save!
811     end
812     it 'コマを含んでいる' do
813       r = SpeechBalloon.show(@sb.id, @author).to_json SpeechBalloon.show_json_opt
814       j = JSON.parse r
815       i = j
816       i.has_key?('panel').should be_true
817     end
818       it 'コマは作家を含んでいる' do
819         r = SpeechBalloon.show(@sb.id, @author).to_json SpeechBalloon.show_json_opt
820         j = JSON.parse r
821         i = j
822         s = i['panel']
823         s.has_key?('author').should be_true
824       end
825     it 'フキダシ枠を含んでいる' do
826       r = SpeechBalloon.show(@sb.id, @author).to_json SpeechBalloon.show_json_opt
827       j = JSON.parse r
828       i = j
829       i.has_key?('balloon').should be_true
830     end
831     it 'セリフを含んでいる' do
832       r = SpeechBalloon.show(@sb.id, @author).to_json SpeechBalloon.show_json_opt
833       j = JSON.parse r
834       i = j
835       i.has_key?('speech').should be_true
836     end
837     it 'フキダシテンプレートを含んでいる' do
838       r = SpeechBalloon.show(@sb.id, @author).to_json SpeechBalloon.show_json_opt
839       j = JSON.parse r
840       i = j
841       i.has_key?('speech_balloon_template').should be_true
842     end
843   end
844 end