OSDN Git Service

t30350#:fix destroy
[pettanr/pettanr.git] / spec / models / comic_spec.rb
1 # -*- encoding: utf-8 -*-
2 require 'spec_helper'
3 #コミック
4
5 describe Comic do
6   before do
7     @admin = FactoryGirl.create :admin
8     @sp = FactoryGirl.create :system_picture
9     @lg = FactoryGirl.create :license_group
10     @license = FactoryGirl.create :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
11     @user = FactoryGirl.create( :user_yas)
12     @author = FactoryGirl.create :author, :user_id => @user.id
13     @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
14     @other_user = FactoryGirl.create( :user_yas)
15     @other_author = FactoryGirl.create :author, :user_id => @other_user.id
16     @other_artist = FactoryGirl.create :artist_yas, :author_id => @other_author.id
17   end
18   
19   describe '検証に於いて' do
20     before do
21       @comic = FactoryGirl.build :comic, :author_id => @author.id
22     end
23     
24     context 'オーソドックスなデータのとき' do
25       it '下限データが通る' do
26         @comic.title = 'a'
27         @comic.visible = 0
28         @comic.should be_valid
29       end
30       it '上限データが通る' do
31         @comic.title = 'a'*100
32         @comic.visible = 1
33         @comic.should be_valid
34       end
35     end
36     
37     context 'titleを検証するとき' do
38       it 'nullなら失敗する' do
39         @comic.title = nil
40         @comic.should_not be_valid
41       end
42       it '100文字以上なら失敗する' do
43         @comic.title = 'a'*101
44         @comic.should_not be_valid
45       end
46     end
47     context 'visibleを検証するとき' do
48       it 'nullなら失敗する' do
49         @comic.visible = nil
50         @comic.should_not be_valid
51       end
52       it '負なら失敗する' do
53         @comic.visible = -1
54         @comic.should_not be_valid
55       end
56       it '2以上なら失敗する' do
57         @comic.visible = 2
58         @comic.should_not be_valid
59       end
60     end
61   end
62   
63   describe 'デフォルト値補充に於いて' do
64     it 'visibleが0になっている' do
65       @comic = FactoryGirl.build :comic, :visible => nil
66       @comic.supply_default
67       @comic.visible.should eq 0
68     end
69   end
70   
71   describe '上書き補充に於いて' do
72     it '作家idが設定されている' do
73       @comic = FactoryGirl.build :comic, :author_id => nil
74       @comic.overwrite @author
75       @comic.author_id.should eq @author.id
76     end
77   end
78   
79   describe '所持判定に於いて' do
80     before do
81       @comic = FactoryGirl.build :comic, :author_id => @author.id
82     end
83     it '自分のコミックならyes' do
84       @comic.own?(@author).should == true
85     end
86     it '他人のコミックならno' do
87       @comic.own?(@other_author).should == false
88     end
89     it 'パラメータが作家でないならno' do
90       @comic.own?(nil).should == false
91     end
92   end
93   
94   describe '閲覧許可に於いて' do
95     before do
96       @comic = FactoryGirl.build :comic, :author_id => @author.id
97     end
98     context '検査対象がnil(ゲスト)のとき' do
99       context 'クローズドモードのとき' do
100         before do
101           MagicNumber['run_mode'] = 1
102         end
103         it '不許可を返す。' do
104           r = @comic.visible?(nil)
105           r.should be_false
106         end
107       end
108       context 'オープンモードのとき' do
109         before do
110           MagicNumber['run_mode'] = 0
111         end
112         it '公開コミックなら許可する' do
113           Comic.any_instance.stub(:visible).and_return(1)
114           r = @comic.visible?(nil)
115           r.should be_true
116         end
117         it '非公開コミックなら許可しない' do
118           Comic.any_instance.stub(:visible).and_return(0)
119           r = @comic.visible?(nil)
120           r.should be_false
121         end
122       end
123     end
124     context '検査対象が作家のとき' do
125       it '自分のコミックなら許可する' do
126         Comic.any_instance.stub(:own?).and_return(true)
127         Comic.any_instance.stub(:visible).and_return(0)
128         r = @comic.visible?(@author)
129         r.should == true
130       end
131       it '他人の非公開コミックなら許可しない' do
132         Comic.any_instance.stub(:own?).and_return(false)
133         Comic.any_instance.stub(:visible).and_return(0)
134         r = @comic.visible?(@author)
135         r.should == false
136       end
137       it '他人のコミックでも公開なら許可する' do
138         Comic.any_instance.stub(:own?).and_return(false)
139         Comic.any_instance.stub(:visible).and_return(1)
140         r = @comic.visible?(@author)
141         r.should == true
142       end
143     end
144     context '検査対象がそれ以外のとき' do
145       it '不許可を返す。' do
146         r = @comic.visible?(@admin)
147         r.should be_false
148       end
149     end
150   end
151   
152   describe '一覧取得に於いて' do
153     before do
154       @comic = FactoryGirl.create :comic, :author_id => @author.id
155     end
156     context 'page補正について' do
157       it '文字列から数値に変換される' do
158         Comic.page('8').should eq 8
159       end
160       it 'nilの場合は1になる' do
161         Comic.page().should eq 1
162       end
163       it '0以下の場合は1になる' do
164         Comic.page('0').should eq 1
165       end
166     end
167     context 'page_size補正について' do
168       it '文字列から数値に変換される' do
169         Comic.page_size('7').should eq 7
170       end
171       it 'nilの場合はComic.default_page_sizeになる' do
172         Comic.page_size().should eq Comic.default_page_size
173       end
174       it '0以下の場合はComic.default_page_sizeになる' do
175         Comic.page_size('0').should eq Comic.default_page_size
176       end
177       it 'Comic.max_page_sizeを超えた場合はComic.max_page_sizeになる' do
178         Comic.page_size('1000').should eq Comic.max_page_size
179       end
180     end
181     context 'つつがなく終わるとき' do
182       it '一覧取得オプションを利用している' do
183         Comic.stub(:list_opt).with(any_args).and_return({})
184         Comic.should_receive(:list_opt).with(any_args).exactly(1)
185         r = Comic.list
186       end
187     end
188     it 'リストを返す' do
189       c = Comic.list
190       c.should eq [@comic]
191     end
192     it '非公開コミックは(自分のコミックであっても)含んでいない' do
193       FactoryGirl.create :comic, :author_id => @author.id, :visible => 0
194       c = Comic.list
195       c.should eq [@comic]
196     end
197     it '時系列で並んでいる' do
198       #公開コミックは(他人のコミックであっても)含んでいる
199       v = FactoryGirl.create :comic, :author_id => @other_author.id, :updated_at => Time.now + 100
200       c = Comic.list
201       c.should eq [v, @comic]
202     end
203     context 'DBに5件あって1ページの件数を2件に変えたとして' do
204       before do
205         @comic2 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 100
206         @comic3 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 200
207         @comic4 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 300
208         @comic5 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 400
209         Comic.stub(:default_page_size).and_return(2)
210       end
211       it '通常は2件を返す' do
212         c = Comic.list
213         c.should have(2).items 
214       end
215       it 'page=1なら末尾2件を返す' do
216         #時系列で並んでいる
217         c = Comic.list(1)
218         c.should eq [@comic5, @comic4]
219       end
220       it 'page=2なら中間2件を返す' do
221         c = Comic.list(2)
222         c.should eq [@comic3, @comic2]
223       end
224       it 'page=3なら先頭1件を返す' do
225         c = Comic.list(3)
226         c.should eq [@comic]
227       end
228     end
229     context 'DBに5件あって1ページの件数を2件に変えたとして' do
230       before do
231         @comic2 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 100
232         @comic3 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 200
233         @comic4 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 300
234         @comic5 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 400
235         Comic.stub(:default_page_size).and_return(2)
236       end
237       it '件数0は全件(5件)を返す' do
238         r = Comic.list 5, 0
239         r.should have(5).items 
240       end
241     end
242   end
243   describe '一覧取得オプションに於いて' do
244     it 'includeキーを含んでいる' do
245       r = Comic.list_opt
246       r.has_key?(:include).should be_true
247     end
248     it '2つの項目を含んでいる' do
249       r = Comic.list_opt[:include]
250       r.should have(2).items
251     end
252     it 'ストーリーを含んでいる' do
253       r = Comic.list_opt[:include]
254       r.has_key?(:stories).should be_true
255     end
256       it 'ストーリーはコマを含んでいる' do
257         r = Comic.list_opt[:include]
258         r[:stories].has_key?(:panel).should be_true
259       end
260     it '作家を含んでいる' do
261       r = Comic.list_opt[:include]
262       r.has_key?(:author).should be_true
263     end
264   end
265   describe 'json一覧出力オプションに於いて' do
266     before do
267       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
268       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
269       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
270       @sbt = FactoryGirl.create :speech_balloon_template
271       @comic = FactoryGirl.create :comic, :author_id => @author.id, :visible => 1
272       @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1
273       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
274     end
275     it 'ストーリーを含んでいる' do
276       r = Comic.list.to_json Comic.list_json_opt
277       j = JSON.parse r
278       i = j.first
279       i.has_key?('stories').should be_true
280     end
281       it 'ストーリーはコマを含んでいる' do
282         r = Comic.list.to_json Comic.list_json_opt
283         j = JSON.parse r
284         i = j.first
285         s = i['stories'].first
286         s.has_key?('panel').should be_true
287       end
288     it '作家を含んでいる' do
289       r = Comic.list.to_json Comic.list_json_opt
290       j = JSON.parse r
291       i = j.first
292       i.has_key?('author').should be_true
293     end
294   end
295   
296   describe '自分のコミック一覧取得に於いて' do
297     before do
298       @comic = FactoryGirl.create :comic, :author_id => @author.id
299     end
300     context 'つつがなく終わるとき' do
301       it '一覧取得オプションを利用している' do
302         Comic.stub(:list_opt).with(any_args).and_return({})
303         Comic.should_receive(:list_opt).with(any_args).exactly(1)
304         r = Comic.mylist @author
305       end
306     end
307     it 'リストを返す' do
308       c = Comic.mylist @author
309       c.should eq [@comic]
310     end
311     it '時系列で並んでいる' do
312       nc = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 100
313       cl = Comic.mylist @author
314       cl.should eq [nc, @comic]
315     end
316     it '他人のコミックは公開でも含まない' do
317       nc = FactoryGirl.create :comic, :author_id => @other_author.id, :visible => 1
318       cl = Comic.mylist @author
319       cl.should eq [@comic]
320     end
321     it '自分のコミックは非公開でも含んでいる' do
322       nc = FactoryGirl.create :comic, :author_id => @author.id, :visible => 0, :updated_at => Time.now + 100
323       cl = Comic.mylist @author
324       cl.should eq [nc, @comic]
325     end
326     context 'DBに5件あって1ページの件数を2件に変えたとして' do
327       before do
328         @comic2 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 100
329         @comic3 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 200
330         @comic4 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 300
331         @comic5 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 400
332       end
333       it '通常は2件を返す' do
334         c = Comic.mylist @author, 1, 2
335         c.should have(2).items 
336       end
337       it 'page=1なら末尾2件を返す' do
338         #時系列で並んでいる
339         c = Comic.mylist(@author, 1, 2)
340         c.should eq [@comic5, @comic4]
341       end
342       it 'page=2なら中間2件を返す' do
343         c = Comic.mylist(@author, 2, 2)
344         c.should eq [@comic3, @comic2]
345       end
346       it 'page=3なら先頭1件を返す' do
347         c = Comic.mylist(@author, 3, 2)
348         c.should eq [@comic]
349       end
350     end
351     context 'DBに5件あって1ページの件数を0件に変えたとして' do
352       before do
353         @comic2 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 100
354         @comic3 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 200
355         @comic4 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 300
356         @comic5 = FactoryGirl.create :comic, :author_id => @author.id, :updated_at => Time.now + 400
357         Author.stub(:default_comic_page_size).and_return(2)
358       end
359       it '通常は全件(5件)を返す' do
360         r = Comic.mylist @author, 5, 0
361         r.should have(5).items 
362       end
363     end
364   end
365   
366   describe '単体取得に於いて' do
367     before do
368       @comic = FactoryGirl.create :comic, :author_id => @author.id
369     end
370     context 'つつがなく終わるとき' do
371       it '単体取得オプションを利用している' do
372         Comic.stub(:show_opt).with(any_args).and_return({})
373         Comic.should_receive(:show_opt).with(any_args).exactly(1)
374         r = Comic.show @comic.id, @author
375       end
376       it '閲覧許可を問い合わせている' do
377         Comic.any_instance.stub(:visible?).with(any_args).and_return(true)
378         Comic.any_instance.should_receive(:visible?).with(any_args).exactly(1)
379         r = Comic.show @comic.id, @author
380       end
381     end
382     it '指定のコミックを返す' do
383       c = Comic.show @comic.id, @author
384       c.should eq @comic
385     end
386     context '閲覧許可が出なかったとき' do
387       it '403Forbidden例外を返す' do
388         Comic.any_instance.stub(:visible?).and_return(false)
389         lambda{
390           Comic.show @comic.id, @author
391         }.should raise_error(ActiveRecord::Forbidden)
392       end
393     end
394     context '存在しないコミックを開こうとしたとき' do
395       it '404RecordNotFound例外を返す' do
396         lambda{
397           Comic.show 110, @author
398         }.should raise_error(ActiveRecord::RecordNotFound)
399       end
400     end
401   end
402   
403   describe '編集取得に於いて' do
404     before do
405       @comic = FactoryGirl.create :comic, :author_id => @author.id
406     end
407     context 'つつがなく終わるとき' do
408       it '単体取得オプションを利用している' do
409         Comic.stub(:show_opt).with(any_args).and_return({})
410         Comic.should_receive(:show_opt).with(any_args).exactly(1)
411         r = Comic.edit @comic.id, @author
412       end
413       it '所持判定を問い合わせている' do
414         Comic.any_instance.stub(:own?).with(any_args).and_return(true)
415         Comic.any_instance.should_receive(:own?).with(any_args).exactly(1)
416         r = Comic.edit @comic.id, @author
417       end
418     end
419     it '指定のコミックを返す' do
420       Comic.any_instance.stub(:own?).and_return(true)
421       c = Comic.edit @comic.id, @author.id
422       c.should eq @comic
423     end
424     context '他人のコミックを開こうとしたとき' do
425       it '403Forbidden例外を返す' do
426         Comic.any_instance.stub(:own?).and_return(false)
427         lambda{
428           Comic.edit @comic.id, @author
429         }.should raise_error(ActiveRecord::Forbidden)
430       end
431     end
432     context '存在しないコミックを開こうとしたとき' do
433       it '404RecordNotFound例外を返す' do
434         lambda{
435           Comic.edit 110, @author
436         }.should raise_error(ActiveRecord::RecordNotFound)
437       end
438     end
439   end
440   describe '単体取得オプションに於いて' do
441     it 'includeキーを含んでいる' do
442       r = Comic.show_opt
443       r.has_key?(:include).should be_true
444     end
445     it '2つの項目を含んでいる' do
446       r = Comic.show_opt[:include]
447       r.should have(2).items
448     end
449     it '作家を含んでいる' do
450       r = Comic.show_opt[:include]
451       r.has_key?(:author).should be_true
452     end
453     it 'ストーリーを含んでいる' do
454       r = Comic.show_opt[:include]
455       r.has_key?(:stories).should be_true
456     end
457       it 'ストーリーはコマを含んでいる' do
458         r = Comic.show_opt[:include]
459         r[:stories].has_key?(:panel).should be_true
460       end
461   end
462   describe 'json単体出力オプションに於いて' do
463     before do
464       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
465       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
466       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :license_id => @license.id, :original_picture_id => @op.id, :picture_id => @p.id
467       @sbt = FactoryGirl.create :speech_balloon_template
468       @comic = FactoryGirl.create :comic, :author_id => @author.id, :visible => 1
469       @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1
470       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
471     end
472     it 'ストーリーを含んでいる' do
473       r = Comic.show(@comic.id, @author).to_json Comic.show_json_opt
474       j = JSON.parse r
475       i = j
476       i.has_key?('stories').should be_true
477     end
478       it 'ストーリーはコマを含んでいる' do
479         r = Comic.show(@comic.id, @author).to_json Comic.show_json_opt
480         j = JSON.parse r
481         i = j
482         s = i['stories'].first
483         s.has_key?('panel').should be_true
484       end
485     it '作家を含んでいる' do
486       r = Comic.show(@comic.id, @author).to_json Comic.show_json_opt
487       j = JSON.parse r
488       i = j
489       i.has_key?('author').should be_true
490     end
491   end
492   
493   describe '削除に於いて' do
494     before do
495       @comic = FactoryGirl.create :comic, :author_id => @author.id
496       @panel = FactoryGirl.create :panel, :author_id => @author.id, :publish => 1
497       @story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @comic.id, :panel_id => @panel.id
498       @other_comic = FactoryGirl.create :comic, :author_id => @author.id
499       @other_story = FactoryGirl.create :story, :author_id => @author.id, :comic_id => @other_comic.id, :panel_id => @panel.id
500     end
501     context 'つつがなく終わるとき' do
502       it '自身を削除する' do
503         lambda {
504           r = @comic.destroy_with_story
505         }.should change(Comic, :count).by(-1)
506         lambda {
507           r = Comic.find @comic.id
508         }.should raise_error
509       end
510       it '自身にリンクしているストーリーをすべて削除する' do
511         lambda {
512           r = @comic.destroy_with_story
513         }.should change(Story, :count).by(-1)
514         lambda {
515           r = Story.find @story.id
516         }.should raise_error
517       end
518       it 'Trueを返す' do
519         r = @comic.destroy_with_story
520         r.should be_true
521       end
522     end
523     context '削除に失敗したとき' do
524       before do
525         Story.any_instance.stub(:destroy).with(any_args).and_return(false)
526       end
527       it 'Falseを返す' do
528         r = @comic.destroy_with_story
529         r.should be_false
530       end
531       it 'ロールバックしている' do
532         lambda {
533           r = @comic.destroy_with_story
534         }.should_not change(Comic, :count)
535         lambda {
536           r = @comic.destroy_with_story
537         }.should_not change(Story, :count)
538       end
539     end
540   end
541 end