OSDN Git Service

merge v04
[pettanr/pettanr.git] / spec / models / original_picture_spec.rb
1 # -*- encoding: utf-8 -*-
2 require 'spec_helper'
3
4 describe OriginalPicture do
5   before do
6     Factory :admin
7     @user = Factory( :user_yas)
8     @author = @user.author
9     @artist = Factory :artist_yas, :author_id => @author.id
10     @other_user = Factory( :user_yas)
11     @other_author = @other_user.author
12     @other_artist = Factory :artist_yas, :author_id => @other_author.id
13     @sp = Factory :system_picture
14     @lg = Factory :license_group
15     @license = Factory :license, :license_group_id => @lg.id, :system_picture_id => @sp.id
16   end
17   
18   describe '検証に於いて' do
19     before do
20     end
21     
22     it 'オーソドックスなデータなら通る' do
23       @op = Factory.build :original_picture, :artist_id => @artist.id
24       @op.should be_valid
25     end
26     
27     context 'extを検証するとき' do
28       before do
29         @op = Factory.build :original_picture, :artist_id => @artist.id
30       end
31       it 'テストデータの確認' do
32         @op.ext = 'jpeg'
33         @op.should be_valid
34       end
35       it 'nullなら失敗する' do
36         @op.ext = ''
37         @op.should_not be_valid
38       end
39       it '5文字以上なら失敗する' do
40         @op.ext = 'a'*5
41         @op.should_not be_valid
42       end
43       it 'png,gif,jpeg以外なら失敗する' do
44         @op.ext = 'bmp'
45         @op.should_not be_valid
46       end
47     end
48     context 'widthを検証するとき' do
49       before do
50         @op = Factory.build :original_picture, :artist_id => @artist.id
51       end
52       it 'テストデータの確認' do
53         @op.width = 1
54         @op.should be_valid
55       end
56       it 'nullなら失敗する' do
57         @op.width = nil
58         @op.should_not be_valid
59       end
60       it '数値でなければ失敗する' do
61         @op.width = 'a'
62         @op.should_not be_valid
63       end
64       it '0なら失敗する' do
65         @op.width = '0'
66         @op.should_not be_valid
67       end
68       it '負でも失敗する' do
69         @op.width = -1
70         @op.should_not be_valid
71       end
72     end
73     context 'heightを検証するとき' do
74       before do
75         @op = Factory.build :original_picture, :artist_id => @artist.id
76       end
77       it 'テストデータの確認' do
78         @op.height = 1
79         @op.should be_valid
80       end
81       it 'nullなら失敗する' do
82         @op.height = nil
83         @op.should_not be_valid
84       end
85       it '数値でなければ失敗する' do
86         @op.height = 'a'
87         @op.should_not be_valid
88       end
89       it '0なら失敗する' do
90         @op.height = '0'
91         @op.should_not be_valid
92       end
93       it '負でも失敗する' do
94         @op.height = -1
95         @op.should_not be_valid
96       end
97     end
98     context 'filesizeを検証するとき' do
99       before do
100         @op = Factory.build :original_picture, :artist_id => @artist.id
101       end
102       it 'テストデータの確認' do
103         @op.filesize = 1
104         @op.should be_valid
105       end
106       it 'nullなら失敗する' do
107         @op.filesize = nil
108         @op.should_not be_valid
109       end
110       it '数値でなければ失敗する' do
111         @op.filesize = 'a'
112         @op.should_not be_valid
113       end
114       it '負なら失敗する' do
115         @op.filesize = '-1'
116         @op.should_not be_valid
117       end
118       it '2MB以上なら失敗する' do
119         @op.filesize = 2000000+1
120         @op.should_not be_valid
121       end
122     end
123     context 'artist_idを検証するとき' do
124       before do
125         @op = Factory.build :original_picture
126       end
127       it 'テストデータの確認' do
128         @op.artist_id = @artist.id
129         @op.should be_valid
130       end
131       it 'nullなら失敗する' do
132         @op.artist_id = nil
133         @op.should_not be_valid
134       end
135       it '数値でなければ失敗する' do
136         @op.artist_id = 'a'
137         @op.should_not be_valid
138       end
139       it '存在する絵師でなければ失敗する' do
140         @op.artist_id = 0
141         @op.should_not be_valid
142       end
143     end
144   end
145   
146   describe 'データ補充に於いて' do
147     before do
148     end
149     
150   end
151   
152   describe '作者判定に於いて' do
153     before do
154     end
155     it '自作の原画ならyes' do
156       op = Factory :original_picture, :artist_id => @artist.id
157       op.own?(@author).should == true
158     end
159     it '他人のならno' do
160       op = Factory :original_picture, :artist_id => @other_artist.id
161       op.own?(@author).should == false
162     end
163     it '作家が不明ならno' do
164       op = Factory :original_picture, :artist_id => @artist.id
165       op.own?(nil).should == false
166     end
167     it '作家が絵師でないならno' do
168       other_user = Factory( :user_yas)
169       op = Factory :original_picture, :artist_id => @artist.id
170       op.own?(@other_author).should == false
171     end
172   end
173   describe '単体取得に於いて' do
174     before do
175       @op = Factory :original_picture, :artist_id => @artist.id
176     end
177     it '指定の原画を返す' do
178       pic = OriginalPicture.show @op.id, @artist
179       pic.should eq @op
180     end
181     context '他人の原画を開こうとしたとき' do
182       it '403Forbidden例外を返す' do
183         lambda{
184           pic = OriginalPicture.show @op.id, @other_artist
185         }.should raise_error(ActiveRecord::Forbidden)
186       end
187     end
188     context '存在しない原画を開こうとしたとき' do
189       it '404RecordNotFound例外を返す' do
190         lambda{
191           pic = OriginalPicture.show 0, @artist
192         }.should raise_error(ActiveRecord::RecordNotFound)
193       end
194     end
195   end
196   describe '編集取得に於いて' do
197     before do
198       @op = Factory :original_picture, :artist_id => @artist.id
199     end
200     it '指定の原画を返す' do
201       pic = OriginalPicture.edit @op.id, @artist
202       pic.should eq @op
203     end
204     context '他人の原画を開こうとしたとき' do
205       it '403Forbidden例外を返す' do
206         lambda{
207           pic = OriginalPicture.edit @op.id, @other_artist
208         }.should raise_error(ActiveRecord::Forbidden)
209       end
210     end
211     context '存在しない原画を開こうとしたとき' do
212       it '404RecordNotFound例外を返す' do
213         lambda{
214           pic = OriginalPicture.edit 0, @artist
215         }.should raise_error(ActiveRecord::RecordNotFound)
216       end
217     end
218   end
219   describe 'json単体出力オプションに於いて' do
220     it 'includeキーを含んでいる' do\r
221       r = OriginalPicture.show_json_include_opt\r
222       r.has_key?(:include).should be_true\r
223     end\r
224     it '1つの項目を含んでいる' do\r
225       r = OriginalPicture.show_json_include_opt[:include]\r
226       r.should have(1).items\r
227     end\r
228     it '素材を含んでいる' do\r
229       r = OriginalPicture.show_json_include_opt[:include]\r
230       r.has_key?(:resource_picture).should be_true\r
231     end\r
232   end
233   describe '一覧取得に於いて' do
234     before do
235       @op = Factory :original_picture, :artist_id => @artist.id
236     end
237     context 'page補正について' do
238       it '文字列から数値に変換される' do
239         OriginalPicture.page('8').should eq 8
240       end
241       it 'nilの場合は1になる' do
242         OriginalPicture.page().should eq 1
243       end
244       it '0以下の場合は1になる' do
245         OriginalPicture.page('0').should eq 1
246       end
247     end
248     context 'page_size補正について' do
249       it '文字列から数値に変換される' do
250         OriginalPicture.page_size('7').should eq 7
251       end
252       it 'nilの場合はOriginalPicture.default_page_sizeになる' do
253         OriginalPicture.page_size().should eq OriginalPicture.default_page_size
254       end
255       it '0以下の場合はOriginalPicture.default_page_sizeになる' do
256         OriginalPicture.page_size('0').should eq OriginalPicture.default_page_size
257       end
258       it 'OriginalPicture.max_page_sizeを超えた場合はOriginalPicture.max_page_sizeになる' do
259         OriginalPicture.page_size('1000').should eq OriginalPicture.max_page_size
260       end
261     end
262     it 'リストを返す' do
263       pic = OriginalPicture.list @artist.id
264       pic.should eq [@op]
265     end
266     it '他人の原画は含んでいない' do
267       Factory :original_picture, :artist_id => @other_artist.id
268       pic = OriginalPicture.list @artist.id
269       pic.should eq [@op]
270     end
271     it '時系列で並んでいる' do
272       newpic = Factory :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 100
273       pic = OriginalPicture.list @artist.id
274       pic.should eq [newpic, @op]
275     end
276     context 'DBに5件あって1ページの件数を2件に変えたとして' do
277       before do
278         @op2 = Factory :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 100
279         @op3 = Factory :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 200
280         @op4 = Factory :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 300
281         @op5 = Factory :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 400
282         OriginalPicture.stub(:default_page_size).and_return(2)
283       end
284       it '通常は2件を返す' do
285         pic = OriginalPicture.list @artist.id
286         pic.should have(2).items 
287       end
288       it 'page=1なら末尾2件を返す' do
289         #時系列で並んでいる
290         pic = OriginalPicture.list( @artist.id, {}, 1)
291         pic.should eq [@op5, @op4]
292       end
293       it 'page=2なら中間2件を返す' do
294         pic = OriginalPicture.list( @artist.id, {}, 2)
295         pic.should eq [@op3, @op2]
296       end
297       it 'page=3なら先頭1件を返す' do
298         pic = OriginalPicture.list( @artist.id, {}, 3)
299         pic.should eq [@op]
300       end
301     end
302   end
303   describe 'list関連テーブルプションに於いて' do\r
304     it 'includeキーを含んでいる' do\r
305       r = OriginalPicture.list_opt\r
306       r.has_key?(:include).should be_true\r
307     end\r
308     it '1つの項目を含んでいる' do\r
309       r = OriginalPicture.list_opt[:include]\r
310       r.should have(1).items\r
311     end\r
312     it '素材を含んでいる' do\r
313       r = OriginalPicture.list_opt[:include]\r
314       r.has_key?(:resource_picture).should be_true\r
315     end\r
316   end
317   describe 'json一覧出力オプションに於いて' do\r
318     it 'includeキーを含んでいる' do\r
319       r = OriginalPicture.list_json_opt\r
320       r.has_key?(:include).should be_true\r
321     end\r
322     it '1つの項目を含んでいる' do\r
323       r = OriginalPicture.list_json_opt[:include]\r
324       r.should have(1).items\r
325     end\r
326     it '素材を含んでいる' do\r
327       r = OriginalPicture.list_json_opt[:include]\r
328       r.has_key?(:resource_picture).should be_true\r
329     end\r
330   end\r
331   describe 'RMagick変換に於いて' do
332     before do
333       @op = Factory.build :original_picture, :artist_id => @artist.id
334     end
335     context 'つつがなく終わるとき' do
336       it '画像データをオブジェクト化している' do
337         Magick::Image.stub(:from_blob).and_return(['mgkobj'])
338         @op.data_to_mgk('mgkbin').should eq 'mgkobj'
339       end
340     end
341     context '失敗するとき' do
342       it 'Falseを返す' do
343         Magick::Image.should_receive(:from_blob).with(any_args).and_raise('StandardError')
344         @op.data_to_mgk('mgkbin').should be_false
345       end
346       it '全体エラーがセットされている' do
347         Magick::Image.should_receive(:from_blob).with(any_args).and_raise('StandardError')
348         lambda {
349           @op.data_to_mgk('mgkbin')
350         }.should change(@op.errors[:base], :count)
351       end
352     end
353   end
354   describe '作成・更新に於いて' do
355     before do
356       @op = Factory.build :original_picture, :artist_id => @artist.id
357       #RMagickのスタブをおいておく
358       class Mgk ; class Image ; end ; end
359       @filesize = 76543
360       Mgk::Image.stub(:from_blob).with(any_args).and_return([Mgk.new])
361       Mgk.any_instance.stub(:format).with(any_args).and_return('png')
362       Mgk.any_instance.stub(:rows).with(any_args).and_return(200)
363       Mgk.any_instance.stub(:columns).with(any_args).and_return(100)
364       Mgk.any_instance.stub(:filesize).with(any_args).and_return(@filesize)
365       Mgk.any_instance.stub(:to_blob).with(any_args).and_return('data')
366       #原画ファイル削除だけは必ず成功するものとしておく
367       PictureIO::LocalPicture.any_instance.stub(:delete).with(any_args).and_return(true)
368       #素材取得は新規作成ケースでテストしておく
369       ResourcePicture.stub(:update_picture).with(any_args).and_return(
370         Factory.build :resource_picture, :artist_id => @artist.id
371       )
372     end
373     context '事前チェック' do
374       before do
375         #すべての処理が正常パターンで通過すれば、一番深い分岐まで通る。
376         #それで外部のメソッド呼び出しだけに着目してテストする。
377         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(Mgk.new)
378         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)\r
379         PictureIO::LocalPicture.any_instance.stub(:put).with(any_args).and_return(true)
380       end
381       it 'RMagick変換を依頼している' do
382         OriginalPicture.any_instance.should_receive(:data_to_mgk).exactly(1)
383         @op.store 'bindata', @artist\r
384       end
385       it '自身に属性をセットしている' do
386         OriginalPicture.any_instance.should_receive(:attributes=).exactly(1)
387         @op.store 'bindata', @artist\r
388       end
389       it '自身が保存されている' do
390         OriginalPicture.any_instance.should_receive(:save).exactly(1)\r
391         @op.store 'bindata', @artist\r
392       end
393       it 'PictureIoに画像データの保存を依頼している' do
394         PictureIO::LocalPicture.any_instance.should_receive(:put).with(any_args).exactly(1)
395         @op.store 'bindata', @artist\r
396       end
397     end
398     context 'つつがなく終わるとき' do
399       before do
400         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
401         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(Mgk.new)
402 #        OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)\r
403         PictureIO::LocalPicture.any_instance.stub(:put).with(any_args).and_return(true)
404       end
405       it '自身に属性をセットしている' do
406         lambda {
407           @op.store 'bindata', @artist\r
408         }.should change @op, :filesize
409       end
410       it '原画モデルが作成されている' do
411         lambda {
412           @op.store 'bindata', @artist
413         }.should change OriginalPicture, :count
414       end
415       it '原画が保存されている' do
416         @op.store 'bindata', @artist
417         OriginalPicture.find(@op).should_not be_nil\r
418       end
419       it 'Trueを返す' do
420         @op.store('bindata', @artist).should eq true\r
421       end
422     end
423     #以下から例外ケース。処理先頭から失敗させていく
424     context 'RMagick変換が失敗したとき' do
425       before do
426         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(false)
427       end
428       it 'falseを返す' do
429         @op.store('bindata', @artist).should be_false\r
430       end
431       it '自身の保存は呼ばれていない' do
432         OriginalPicture.any_instance.should_not_receive(:save)\r
433         @op.store('bindata', @artist)\r
434       end
435     end
436     context '自身の保存に失敗したとき' do
437       before do
438         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(Mgk.new)
439         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(false)\r
440       end
441       it 'falseを返す' do
442         @op.store('bindata', @artist).should be_false\r
443       end
444       it '更新されていない' do
445         @op.store('bindata', @artist)
446         @op.should be_a_new OriginalPicture\r
447       end
448       it '原画の保存は呼ばれていない' do
449         PictureIO::LocalPicture.any_instance.should_not_receive(:put)\r
450       end
451     end
452     context '原画の保存に失敗したとき' do
453       before do
454         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(Mgk.new)
455         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)\r
456         PictureIO::LocalPicture.any_instance.stub(:put).with(any_args).and_return(false)
457       end
458       it 'falseを返す' do
459         @op.store('bindata', @artist).should be_false\r
460       end
461       it '更新されていない' do
462         @op.store('bindata', @artist)\r
463         @op.should be_a_new OriginalPicture\r
464       end
465       it '対象素材オブジェクトの保存は呼ばれていない' do
466         ResourcePicture.any_instance.should_not_receive(:save)\r
467         @op.store('bindata', @artist)\r
468       end
469       it '全体エラーメッセージがセットされている' do
470         lambda {
471           @op.store('bindata', @artist)\r
472         }.should change(@op.errors[:base], :count)
473       end
474     end
475   end
476 end