OSDN Git Service

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