OSDN Git Service

b3327704e9a0e7716ff4a56e61af663906d447fa
[pettanr/pettanr.git] / spec / models / original_picture_spec.rb
1 # -*- encoding: utf-8 -*-
2 #原画
3 require 'spec_helper'
4
5 describe OriginalPicture do
6   before do
7     FactoryGirl.create :admin
8     @user = FactoryGirl.create( :user_yas)
9     @author = @user.author
10     @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
11     @other_user = FactoryGirl.create( :user_yas)
12     @other_author = @other_user.author
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   end
18   
19   describe '検証に於いて' do
20     before do
21       @op = FactoryGirl.build :original_picture, :artist_id => @artist.id
22     end
23     
24     context 'オーソドックスなデータのとき' do
25       it '下限データが通る' do
26         @op.ext = 'png' #リストにない拡張子は通らないし
27         @op.width = 1
28         @op.height = 1
29         @op.filesize = 1
30         @op.md5 = 'a'*32
31         @op.should be_valid
32       end
33       it '上限データが通る' do
34         @op.ext = 'jpeg'
35         @op.width = 99999
36         @op.height = 99999
37         @op.filesize = 2000000
38         @op.md5 = 'a'*32
39         @op.should be_valid
40       end
41     end
42     
43     context 'extを検証するとき' do
44       it 'nullなら失敗する' do
45         @op.ext = ''
46         @op.should_not be_valid
47       end
48       it '5文字以上なら失敗する' do
49         @op.ext = 'a'*5
50         @op.should_not be_valid
51       end
52       it 'png,gif,jpeg以外なら失敗する' do
53         @op.ext = 'bmp'
54         @op.should_not be_valid
55       end
56     end
57     context 'widthを検証するとき' do
58       it 'nullなら失敗する' do
59         @op.width = nil
60         @op.should_not be_valid
61       end
62       it '数値でなければ失敗する' do
63         @op.width = 'a'
64         @op.should_not be_valid
65       end
66       it '0なら失敗する' do
67         @op.width = '0'
68         @op.should_not be_valid
69       end
70       it '負でも失敗する' do
71         @op.width = -1
72         @op.should_not be_valid
73       end
74     end
75     context 'heightを検証するとき' do
76       it 'nullなら失敗する' do
77         @op.height = nil
78         @op.should_not be_valid
79       end
80       it '数値でなければ失敗する' do
81         @op.height = 'a'
82         @op.should_not be_valid
83       end
84       it '0なら失敗する' do
85         @op.height = '0'
86         @op.should_not be_valid
87       end
88       it '負でも失敗する' do
89         @op.height = -1
90         @op.should_not be_valid
91       end
92     end
93     context 'filesizeを検証するとき' do
94       it 'nullなら失敗する' do
95         @op.filesize = nil
96         @op.should_not be_valid
97       end
98       it '数値でなければ失敗する' do
99         @op.filesize = 'a'
100         @op.should_not be_valid
101       end
102       it '負なら失敗する' do
103         @op.filesize = '-1'
104         @op.should_not be_valid
105       end
106       it '2MB以上なら失敗する' do
107         @op.filesize = 2000000+1
108         @op.should_not be_valid
109       end
110     end
111     context 'artist_idを検証するとき' do
112       it 'nullなら失敗する' do
113         @op.artist_id = nil
114         @op.should_not be_valid
115       end
116       it '数値でなければ失敗する' do
117         @op.artist_id = 'a'
118         @op.should_not be_valid
119       end
120       it '存在する絵師でなければ失敗する' do
121         @op.artist_id = 0
122         @op.should_not be_valid
123       end
124     end
125     context 'md5を検証するとき' do
126       it 'nullなら失敗する' do
127         @op.md5 = ''
128         @op.should_not be_valid
129       end
130       it '31文字なら失敗する' do
131         @op.md5 = 'a'*31
132         @op.should_not be_valid
133       end
134       it '33文字なら失敗する' do
135         @op.md5 = 'a'*33
136         @op.should_not be_valid
137       end
138     end
139   end
140   
141   describe 'デフォルト値補充に於いて' do
142     it 'defined' do
143       @op = FactoryGirl.build :original_picture, :artist_id => @artist.id
144       @op.supply_default
145     end
146   end
147   
148   describe '上書き補充に於いて' do
149     it '絵師idが設定されている' do
150       @op = FactoryGirl.build :original_picture, :artist_id => nil
151       @op.overwrite @artist
152       @op.artist_id.should eq @artist.id
153     end
154   end
155   
156   describe '作者判定に於いて' do
157     before do
158     end
159     it '自作の原画ならyes' do
160       op = FactoryGirl.create :original_picture, :artist_id => @artist.id
161       op.own?(@artist).should == true
162     end
163     it '他人のならno' do
164       op = FactoryGirl.create :original_picture, :artist_id => @other_artist.id
165       op.own?(@artist).should == false
166     end
167   end
168   
169   describe '閲覧許可に於いて' do
170     before do
171       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
172     end
173     it '自分の原画を見るときは許可する' do\r
174       OriginalPicture.any_instance.stub(:own?).and_return(true)\r
175       r = @op.visible?(@artist)
176       r.should == true
177     end\r
178     it '他人の原画なら許可しない' do\r
179       OriginalPicture.any_instance.stub(:own?).and_return(false)\r
180       r = @op.visible?(@artist)
181       r.should == false
182     end\r
183   end
184   
185   #大文字混じりは検証ではねているので、無用になっている
186   describe '拡張子に於いて' do
187     before do
188       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id, :ext => 'jpeg'
189     end
190     it '画像ファイル拡張子を英数小文字で返す' do\r
191       r = @op.dext
192       r.should eq 'jpeg'
193     end\r
194   end
195   
196   describe 'ファイル名に於いて' do
197     before do
198       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
199       OriginalPicture.any_instance.stub(:dext).and_return('gif')
200     end
201     it '拡張子取得を依頼している' do
202       OriginalPicture.any_instance.should_receive(:dext).exactly(1)
203       @op.filename
204     end
205     it 'id+拡張子のフォーマットで返す' do\r
206       r = @op.filename
207       r.should eq "#{@op.id}.gif"
208     end\r
209   end
210   
211   describe 'MimeTypeに於いて' do
212     before do
213       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
214       OriginalPicture.any_instance.stub(:dext).and_return('gif')
215     end
216     it '拡張子取得を依頼している' do
217       OriginalPicture.any_instance.should_receive(:dext).exactly(1)
218       @op.mime_type
219     end
220     it 'image/拡張子のフォーマットで返す' do\r
221       r = @op.mime_type
222       r.should eq "image/gif"
223     end\r
224   end
225   
226   describe 'ファイルのurlに於いて' do
227     before do
228       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
229       OriginalPicture.any_instance.stub(:filename).and_return('3.gif')
230     end
231     it 'ファイル名取得を依頼している' do
232       OriginalPicture.any_instance.should_receive(:filename).exactly(1)
233       @op.url
234     end
235     it '/original_pictures/3.gifのフォーマットで返す' do\r
236       r = @op.url
237       r.should eq "/original_pictures/3.gif"
238     end\r
239   end
240   
241   describe '画像タグオプションに於いて' do
242     before do
243       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
244       OriginalPicture.any_instance.stub(:url).and_return('/original_pictures/3.gif')
245       ResourcePicture.stub(:fix_size_both).with(any_args).and_return([40, 30])
246     end
247     it 'サムネイル画像の幅高さ取得を依頼している' do
248       ResourcePicture.should_receive(:fix_size_both).with(any_args).exactly(1)
249       @op.opt_img_tag
250     end
251     it '戻り値はHashで返す' do\r
252       r = @op.opt_img_tag
253       r.is_a?(Hash).should be_true
254     end\r
255     it 'srcキーを含んでいる' do
256       r = @op.opt_img_tag
257       r.has_key?(:src).should be_true
258       r[:src].should eq '/original_pictures/3.gif'
259     end
260     it 'widthキーを含んでいる' do
261       r = @op.opt_img_tag
262       r.has_key?(:width).should be_true
263       r[:width].should eq 40
264     end
265     it 'heightキーを含んでいる' do
266       r = @op.opt_img_tag
267       r.has_key?(:height).should be_true
268       r[:height].should eq 30
269     end
270   end
271   
272   describe '一覧取得に於いて' do
273     before do
274       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
275     end
276     context 'page補正について' do
277       it '文字列から数値に変換される' do
278         OriginalPicture.page('8').should eq 8
279       end
280       it 'nilの場合は1になる' do
281         OriginalPicture.page().should eq 1
282       end
283       it '0以下の場合は1になる' do
284         OriginalPicture.page('0').should eq 1
285       end
286     end
287     context 'page_size補正について' do
288       it '文字列から数値に変換される' do
289         OriginalPicture.page_size('7').should eq 7
290       end
291       it 'nilの場合はOriginalPicture.default_page_sizeになる' do
292         OriginalPicture.page_size().should eq OriginalPicture.default_page_size
293       end
294       it '0以下の場合はOriginalPicture.default_page_sizeになる' do
295         OriginalPicture.page_size('0').should eq OriginalPicture.default_page_size
296       end
297       it 'OriginalPicture.max_page_sizeを超えた場合はOriginalPicture.max_page_sizeになる' do
298         OriginalPicture.page_size('1000').should eq OriginalPicture.max_page_size
299       end
300     end
301   end
302   describe 'list関連テーブルプションに於いて' do
303     it 'includeキーを含んでいる' do
304       r = OriginalPicture.list_opt
305       r.has_key?(:include).should be_true
306     end
307     it '2つの項目を含んでいる' do
308       r = OriginalPicture.list_opt[:include]
309       r.should have(2).items
310     end
311     it '素材を含んでいる' do
312       r = OriginalPicture.list_opt[:include]
313       r.has_key?(:resource_picture).should be_true
314     end
315     it '実素材を含んでいる' do
316       r = OriginalPicture.list_opt[:include]
317       r.has_key?(:pictures).should be_true
318     end
319   end
320   describe 'json一覧出力オプションに於いて' do
321     it 'includeキーを含んでいる' do
322       r = OriginalPicture.list_json_opt
323       r.has_key?(:include).should be_true
324     end
325     it '2つの項目を含んでいる' do
326       r = OriginalPicture.list_json_opt[:include]
327       r.should have(2).items
328     end
329     it '素材を含んでいる' do
330       r = OriginalPicture.list_json_opt[:include]
331       r.has_key?(:resource_picture).should be_true
332     end
333     it '実素材を含んでいる' do
334       r = OriginalPicture.list_json_opt[:include]
335       r.has_key?(:pictures).should be_true
336     end
337   end
338   
339   describe '自分のコミック一覧取得に於いて' do
340     before do
341       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
342     end
343     context 'つつがなく終わるとき' do\r
344       it '一覧取得オプションを利用している' do\r
345         OriginalPicture.stub(:list_opt).with(any_args).and_return({})\r
346         OriginalPicture.should_receive(:list_opt).with(any_args).exactly(1)\r
347         r = OriginalPicture.mylist @artist
348       end\r
349     end\r
350     it 'リストを返す' do
351       r = OriginalPicture.mylist @artist
352       r.should eq [@op]
353     end
354     it '時系列で並んでいる' do
355       nc = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 100
356       r = OriginalPicture.mylist @artist
357       r.should eq [nc, @op]
358     end
359     it '他人のコミックはxxxでも含まない' do
360       nc = FactoryGirl.create :original_picture, :artist_id => @other_artist.id
361       r = OriginalPicture.mylist @artist
362       r.should eq [@op]
363     end
364     it '自分のコミックはxxxでも含んでいる' do
365       nc = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 100
366       r = OriginalPicture.mylist @artist
367       r.should eq [nc, @op]
368     end
369     context 'DBに5件あって1ページの件数を2件に変えたとして' do
370       before do
371         @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 100
372         @op3 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 200
373         @op4 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 300
374         @op5 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 400
375       end
376       it '通常は2件を返す' do
377         r = OriginalPicture.mylist @artist, 1, 2
378         r.should have(2).items 
379       end
380       it 'page=1なら末尾2件を返す' do
381         #時系列で並んでいる
382         r = OriginalPicture.mylist @artist, 1, 2
383         r.should eq [@op5, @op4]
384       end
385       it 'page=2なら中間2件を返す' do
386         r = OriginalPicture.mylist @artist, 2, 2
387         r.should eq [@op3, @op2]
388       end
389       it 'page=3なら先頭1件を返す' do
390         r = OriginalPicture.mylist @artist, 3, 2
391         r.should eq [@op]
392       end
393     end
394     context 'DBに5件あって1ページの件数を0件に変えたとして' do
395       before do
396         @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 100
397         @op3 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 200
398         @op4 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 300
399         @op5 = FactoryGirl.create :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 400
400       end
401       it '通常は全件(5件)を返す' do
402         r = OriginalPicture.mylist @artist, 5, 0
403         r.should have(5).items 
404       end
405     end
406   end
407   
408   describe '更新履歴一覧取得に於いて' do
409     before do
410       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
411       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
412         :original_picture_id => @op.id
413       @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
414     end
415     it 'リストを返す' do
416       r = @op.history
417       r.should eq [@p]
418     end
419     it '他の原画の実素材は含んでいない' do
420       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
421         :original_picture_id => @op2.id
422       r = @op.history
423       r.should eq [@p]
424     end
425     it 'revisionで並んでいる' do
426       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
427         :original_picture_id => @op.id
428       r = @op.history
429       r.should eq [@p2, @p]
430     end
431   end
432   
433   describe '単体取得に於いて' do
434     before do
435       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
436     end
437     context 'つつがなく終わるとき' do\r
438       it '単体取得オプションを利用している' do\r
439         OriginalPicture.stub(:show_opt).with(any_args).and_return({})\r
440         OriginalPicture.should_receive(:show_opt).with(any_args).exactly(1)\r
441         r = OriginalPicture.show @op.id, @artist
442       end\r
443       it '閲覧許可を問い合わせている' do\r
444         OriginalPicture.any_instance.stub(:visible?).with(any_args).and_return(true)\r
445         OriginalPicture.any_instance.should_receive(:visible?).with(any_args).exactly(1)\r
446         r = OriginalPicture.show @op.id, @artist
447       end\r
448     end\r
449     it '指定の原画を返す' do
450       pic = OriginalPicture.show @op.id, @artist
451       pic.should eq @op
452     end
453     context '他人の原画を開こうとしたとき' do
454       it '403Forbidden例外を返す' do
455         OriginalPicture.any_instance.stub(:visible?).and_return(false)\r
456         lambda{
457           pic = OriginalPicture.show @op.id, @other_artist
458         }.should raise_error(ActiveRecord::Forbidden)
459       end
460     end
461     context '存在しない原画を開こうとしたとき' do
462       it '404RecordNotFound例外を返す' do
463         lambda{
464           pic = OriginalPicture.show 0, @artist
465         }.should raise_error(ActiveRecord::RecordNotFound)
466       end
467     end
468   end
469   describe '編集取得に於いて' do
470     before do
471       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
472     end
473     context 'つつがなく終わるとき' do\r
474       it '単体取得オプションを利用している' do\r
475         OriginalPicture.stub(:show_opt).with(any_args).and_return({})\r
476         OriginalPicture.should_receive(:show_opt).with(any_args).exactly(1)\r
477         r = OriginalPicture.edit @op.id, @artist
478       end\r
479       it '所持判定を問い合わせている' do\r
480         OriginalPicture.any_instance.stub(:own?).with(any_args).and_return(true)\r
481         OriginalPicture.any_instance.should_receive(:own?).with(any_args).exactly(1)\r
482         r = OriginalPicture.edit @op.id, @artist
483       end\r
484     end\r
485     it '指定の原画を返す' do
486       pic = OriginalPicture.edit @op.id, @artist
487       pic.should eq @op
488     end
489     context '他人の原画を開こうとしたとき' do
490       it '403Forbidden例外を返す' do
491         OriginalPicture.any_instance.stub(:own?).and_return(false)
492         lambda{
493           r = OriginalPicture.edit @op.id, @other_artist
494         }.should raise_error(ActiveRecord::Forbidden)
495       end
496     end
497     context '存在しない原画を開こうとしたとき' do
498       it '404RecordNotFound例外を返す' do
499         lambda{
500           r = OriginalPicture.edit 0, @artist
501         }.should raise_error(ActiveRecord::RecordNotFound)
502       end
503     end
504   end
505   describe '単体出力オプションに於いて' do
506     it 'includeキーを含んでいる' do
507       r = OriginalPicture.show_opt
508       r.has_key?(:include).should be_true
509     end
510     it '2つの項目を含んでいる' do
511       r = OriginalPicture.show_opt[:include]
512       r.should have(2).items
513     end
514     it '素材を含んでいる' do
515       r = OriginalPicture.show_opt[:include]
516       r.has_key?(:resource_picture).should be_true
517     end
518     it '実素材を含んでいる' do
519       r = OriginalPicture.show_opt[:include]
520       r.has_key?(:pictures).should be_true
521     end
522   end
523   describe 'json単体出力オプションに於いて' do
524     it 'includeキーを含んでいる' do
525       r = OriginalPicture.show_json_opt
526       r.has_key?(:include).should be_true
527     end
528     it '2つの項目を含んでいる' do
529       r = OriginalPicture.show_json_opt[:include]
530       r.should have(2).items
531     end
532     it '素材を含んでいる' do
533       r = OriginalPicture.show_json_opt[:include]
534       r.has_key?(:resource_picture).should be_true
535     end
536     it '実素材を含んでいる' do
537       r = OriginalPicture.show_json_opt[:include]
538       r.has_key?(:pictures).should be_true
539     end
540   end
541   describe 'RMagick変換に於いて' do
542     before do
543       @op = FactoryGirl.build :original_picture, :artist_id => @artist.id
544     end
545     context 'つつがなく終わるとき' do
546       it '画像データをオブジェクト化している' do
547         Magick::Image.stub(:from_blob).and_return(['mgkobj'])
548         @op.data_to_mgk('mgkbin').should eq 'mgkobj'
549       end
550     end
551     context '失敗するとき' do
552       it 'Falseを返す' do
553         Magick::Image.should_receive(:from_blob).with(any_args).and_raise('StandardError')
554         @op.data_to_mgk('mgkbin').should be_false
555       end
556       it '全体エラーがセットされている' do
557         Magick::Image.should_receive(:from_blob).with(any_args).and_raise('StandardError')
558         lambda {
559           @op.data_to_mgk('mgkbin')
560         }.should change(@op.errors[:base], :count)
561       end
562     end
563   end
564   describe '作成・更新に於いて' do
565     before do
566       @op = FactoryGirl.build :original_picture, :artist_id => @artist.id
567       @bd = File.open(Rails.root + 'spec/StandardA.gif', 'rb').read
568     end
569     context '事前チェック' do
570       before do
571         #すべての処理が正常パターンで通過すれば、一番深い分岐まで通る。
572         #それで外部のメソッド呼び出しだけに着目してテストする。
573         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)
574         PictureIO::LocalPicture.any_instance.stub(:put).with(any_args).and_return(true)
575       end
576       it 'RMagick変換を依頼している' do
577         OriginalPicture.any_instance.should_receive(:data_to_mgk).exactly(1)
578         @op.store @bd, @artist
579       end
580       it '自身に属性をセットしている' do
581         OriginalPicture.any_instance.should_receive(:attributes=).exactly(1)
582         @op.store @bd, @artist
583       end
584       it '自身が保存されている' do
585         OriginalPicture.any_instance.should_receive(:save).exactly(1)
586         @op.store @bd, @artist
587       end
588       it 'PictureIoに画像データの保存を依頼している' do
589         PictureIO::LocalPicture.any_instance.should_receive(:put).with(any_args).exactly(1)
590         @op.store @bd, @artist
591       end
592     end
593     context 'つつがなく終わるとき' do
594       before do
595         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
596 #        OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)
597 #        PictureIO::LocalPicture.any_instance.stub(:put).with(any_args).and_return(true)
598       end
599       it '自身に属性をセットしている' do
600         lambda {
601           @op.store @bd, @artist
602         }.should change @op, :filesize
603       end
604       it '原画モデルが作成されている' do
605         lambda {
606           @op.store @bd, @artist
607         }.should change OriginalPicture, :count
608       end
609       it '原画が保存されている' do
610         @op.store @bd, @artist
611         OriginalPicture.find(@op).should_not be_nil
612       end
613       it 'Trueを返す' do
614         @op.store(@bd, @artist).should eq true
615       end
616     end
617     #以下から例外ケース。処理先頭から失敗させていく
618     context 'RMagick変換が失敗したとき' do
619       before do
620         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(false)
621       end
622       it 'falseを返す' do
623         @op.store(@bd, @artist).should be_false
624       end
625       it '自身の保存は呼ばれていない' do
626         OriginalPicture.any_instance.should_not_receive(:save)
627         @op.store(@bd, @artist)
628       end
629     end
630     context '自身の保存に失敗したとき' do
631       before do
632         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(false)
633       end
634       it 'falseを返す' do
635         @op.store(@bd, @artist).should be_false
636       end
637       it '更新されていない' do
638         @op.store(@bd, @artist)
639         @op.should be_a_new OriginalPicture
640       end
641       it '原画の保存は呼ばれていない' do
642         PictureIO::LocalPicture.any_instance.should_not_receive(:put)
643       end
644     end
645     context '原画の保存に失敗したとき' do
646       before do
647         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)
648         PictureIO::LocalPicture.any_instance.stub(:put).with(any_args).and_return(false)
649       end
650       it 'falseを返す' do
651         @op.store(@bd, @artist).should be_false
652       end
653       it '更新されていない' do
654         @op.store(@bd, @artist)
655         @op.should be_a_new OriginalPicture
656       end
657       it '対象素材オブジェクトの保存は呼ばれていない' do
658         ResourcePicture.any_instance.should_not_receive(:save)
659         @op.store(@bd, @artist)
660       end
661       it '全体エラーメッセージがセットされている' do
662         lambda {
663           @op.store(@bd, @artist)
664         }.should change(@op.errors[:base], :count)
665       end
666     end
667   end
668 end