OSDN Git Service

build pictures
[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\r
197     context 'オプションがないとき' do\r
198       it '1つの項目を含んでいる' do\r
199         r = OriginalPicture.show_include_opt\r
200         r.should have(1).items\r
201       end\r
202       it '素材を含んでいる' do\r
203         r = OriginalPicture.show_include_opt\r
204         r.has_key?(:resource_picture).should be_true\r
205       end\r
206     end\r
207     context 'オプションでtestを含ませたとき' do\r
208       it '2つの項目を含んでいる' do\r
209         r = OriginalPicture.show_include_opt(:include => {:test => {}})\r
210         r.should have(2).items\r
211       end\r
212       it 'testを含んでいる' do\r
213         r = OriginalPicture.show_include_opt(:include => {:test => {}})\r
214         r.has_key?(:test).should be_true\r
215       end\r
216     end\r
217   end
218   describe 'json単体出力オプションに於いて' do
219     it 'includeキーを含んでいる' do\r
220       r = OriginalPicture.show_json_include_opt\r
221       r.has_key?(:include).should be_true\r
222     end\r
223     it '1つの項目を含んでいる' do\r
224       r = OriginalPicture.show_json_include_opt[:include]\r
225       r.should have(1).items\r
226     end\r
227     it '素材を含んでいる' do\r
228       r = OriginalPicture.show_json_include_opt[:include]\r
229       r.has_key?(:resource_picture).should be_true\r
230     end\r
231   end
232   describe '一覧取得に於いて' do
233     before do
234       @op = Factory :original_picture, :artist_id => @artist.id
235     end
236     context 'page補正について' do
237       it '文字列から数値に変換される' do
238         OriginalPicture.page('8').should eq 8
239       end
240       it 'nilの場合は1になる' do
241         OriginalPicture.page().should eq 1
242       end
243       it '0以下の場合は1になる' do
244         OriginalPicture.page('0').should eq 1
245       end
246     end
247     context 'page_size補正について' do
248       it '文字列から数値に変換される' do
249         OriginalPicture.page_size('7').should eq 7
250       end
251       it 'nilの場合はOriginalPicture.default_page_sizeになる' do
252         OriginalPicture.page_size().should eq OriginalPicture.default_page_size
253       end
254       it '0以下の場合はOriginalPicture.default_page_sizeになる' do
255         OriginalPicture.page_size('0').should eq OriginalPicture.default_page_size
256       end
257       it 'OriginalPicture.max_page_sizeを超えた場合はOriginalPicture.max_page_sizeになる' do
258         OriginalPicture.page_size('1000').should eq OriginalPicture.max_page_size
259       end
260     end
261     it 'リストを返す' do
262       pic = OriginalPicture.list @artist.id
263       pic.should eq [@op]
264     end
265     it '他人の原画は含んでいない' do
266       Factory :original_picture, :artist_id => @other_artist.id
267       pic = OriginalPicture.list @artist.id
268       pic.should eq [@op]
269     end
270     it '時系列で並んでいる' do
271       newpic = Factory :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 100
272       pic = OriginalPicture.list @artist.id
273       pic.should eq [newpic, @op]
274     end
275     context 'DBに5件あって1ページの件数を2件に変えたとして' do
276       before do
277         @op2 = Factory :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 100
278         @op3 = Factory :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 200
279         @op4 = Factory :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 300
280         @op5 = Factory :original_picture, :artist_id => @artist.id, :updated_at => Time.now + 400
281         OriginalPicture.stub(:default_page_size).and_return(2)
282       end
283       it '通常は2件を返す' do
284         pic = OriginalPicture.list @artist.id
285         pic.should have(2).items 
286       end
287       it 'page=1なら末尾2件を返す' do
288         #時系列で並んでいる
289         pic = OriginalPicture.list( @artist.id, {}, 1)
290         pic.should eq [@op5, @op4]
291       end
292       it 'page=2なら中間2件を返す' do
293         pic = OriginalPicture.list( @artist.id, {}, 2)
294         pic.should eq [@op3, @op2]
295       end
296       it 'page=3なら先頭1件を返す' do
297         pic = OriginalPicture.list( @artist.id, {}, 3)
298         pic.should eq [@op]
299       end
300     end
301   end
302   describe 'list関連テーブルプションに於いて' do\r
303     it 'includeキーを含んでいる' do\r
304       r = OriginalPicture.list_opt\r
305       r.has_key?(:include).should be_true\r
306     end\r
307     it '1つの項目を含んでいる' do\r
308       r = OriginalPicture.list_opt[:include]\r
309       r.should have(1).items\r
310     end\r
311     it '素材を含んでいる' do\r
312       r = OriginalPicture.list_opt[:include]\r
313       r.has_key?(:resource_picture).should be_true\r
314     end\r
315   end
316   describe 'json一覧出力オプションに於いて' do\r
317     it 'includeキーを含んでいる' do\r
318       r = OriginalPicture.list_json_opt\r
319       r.has_key?(:include).should be_true\r
320     end\r
321     it '1つの項目を含んでいる' do\r
322       r = OriginalPicture.list_json_opt[:include]\r
323       r.should have(1).items\r
324     end\r
325     it '素材を含んでいる' do\r
326       r = OriginalPicture.list_json_opt[:include]\r
327       r.has_key?(:resource_picture).should be_true\r
328     end\r
329   end\r
330   describe 'RMagick変換に於いて' do
331     before do
332       @op = Factory.build :original_picture, :artist_id => @artist.id
333     end
334     context 'つつがなく終わるとき' do
335       it '画像データをオブジェクト化している' do
336         Magick::Image.stub(:from_blob).and_return(['mgkobj'])
337         @op.data_to_mgk('mgkbin').should eq 'mgkobj'
338       end
339     end
340     context '失敗するとき' do
341       it 'Falseを返す' do
342         Magick::Image.should_receive(:from_blob).with(any_args).and_raise('StandardError')
343         @op.data_to_mgk('mgkbin').should be_false
344       end
345       it '全体エラーがセットされている' do
346         Magick::Image.should_receive(:from_blob).with(any_args).and_raise('StandardError')
347         lambda {
348           @op.data_to_mgk('mgkbin')
349         }.should change(@op.errors[:base], :count)
350       end
351     end
352   end
353   describe '作成・更新に於いて' do
354     before do
355       @op = Factory.build :original_picture, :artist_id => @artist.id
356       #RMagickのスタブをおいておく
357       class Mgk ; class Image ; end ; end
358       @filesize = 76543
359       Mgk::Image.stub(:from_blob).with(any_args).and_return([Mgk.new])
360       Mgk.any_instance.stub(:format).with(any_args).and_return('png')
361       Mgk.any_instance.stub(:rows).with(any_args).and_return(200)
362       Mgk.any_instance.stub(:columns).with(any_args).and_return(100)
363       Mgk.any_instance.stub(:filesize).with(any_args).and_return(@filesize)
364       Mgk.any_instance.stub(:to_blob).with(any_args).and_return('data')
365       #原画ファイル削除だけは必ず成功するものとしておく
366       PictureIO::LocalPicture.any_instance.stub(:delete).with(any_args).and_return(true)
367       #素材取得は新規作成ケースでテストしておく
368       ResourcePicture.stub(:update_picture).with(any_args).and_return(
369         Factory.build :resource_picture, :artist_id => @artist.id
370       )
371     end
372     context '事前チェック' do
373       before do
374         #すべての処理が正常パターンで通過すれば、一番深い分岐まで通る。
375         #それで外部のメソッド呼び出しだけに着目してテストする。
376         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(Mgk.new)
377         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)\r
378         PictureIO::LocalPicture.any_instance.stub(:put).with(any_args).and_return(true)
379       end
380       it 'RMagick変換を依頼している' do
381         OriginalPicture.any_instance.should_receive(:data_to_mgk).exactly(1)
382         @op.store 'bindata', @artist\r
383       end
384       it '自身に属性をセットしている' do
385         OriginalPicture.any_instance.should_receive(:attributes=).exactly(1)
386         @op.store 'bindata', @artist\r
387       end
388       it '自身が保存されている' do
389         OriginalPicture.any_instance.should_receive(:save).exactly(1)\r
390         @op.store 'bindata', @artist\r
391       end
392       it 'PictureIoに画像データの保存を依頼している' do
393         PictureIO::LocalPicture.any_instance.should_receive(:put).with(any_args).exactly(1)
394         @op.store 'bindata', @artist\r
395       end
396     end
397     context 'つつがなく終わるとき' do
398       before do
399         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
400         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(Mgk.new)
401 #        OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)\r
402         PictureIO::LocalPicture.any_instance.stub(:put).with(any_args).and_return(true)
403       end
404       it '自身に属性をセットしている' do
405         lambda {
406           @op.store 'bindata', @artist\r
407         }.should change @op, :filesize
408       end
409       it '原画モデルが作成されている' do
410         lambda {
411           @op.store 'bindata', @artist
412         }.should change OriginalPicture, :count
413       end
414       it '原画が保存されている' do
415         @op.store 'bindata', @artist
416         OriginalPicture.find(@op).should_not be_nil\r
417       end
418       it 'Trueを返す' do
419         @op.store('bindata', @artist).should eq true\r
420       end
421     end
422     #以下から例外ケース。処理先頭から失敗させていく
423     context 'RMagick変換が失敗したとき' do
424       before do
425         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(false)
426       end
427       it 'falseを返す' do
428         @op.store('bindata', @artist).should be_false\r
429       end
430       it '自身の保存は呼ばれていない' do
431         OriginalPicture.any_instance.should_not_receive(:save)\r
432         @op.store('bindata', @artist)\r
433       end
434     end
435     context '自身の保存に失敗したとき' do
436       before do
437         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(Mgk.new)
438         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(false)\r
439       end
440       it 'falseを返す' do
441         @op.store('bindata', @artist).should be_false\r
442       end
443       it '更新されていない' do
444         @op.store('bindata', @artist)
445         @op.should be_a_new OriginalPicture\r
446       end
447       it '原画の保存は呼ばれていない' do
448         PictureIO::LocalPicture.any_instance.should_not_receive(:put)\r
449       end
450     end
451     context '原画の保存に失敗したとき' do
452       before do
453         OriginalPicture.any_instance.stub(:data_to_mgk).with(any_args).and_return(Mgk.new)
454         OriginalPicture.any_instance.stub(:save).with(any_args).and_return(true)\r
455         PictureIO::LocalPicture.any_instance.stub(:put).with(any_args).and_return(false)
456       end
457       it 'falseを返す' do
458         @op.store('bindata', @artist).should be_false\r
459       end
460       it '更新されていない' do
461         @op.store('bindata', @artist)\r
462         @op.should be_a_new OriginalPicture\r
463       end
464       it '対象素材オブジェクトの保存は呼ばれていない' do
465         ResourcePicture.any_instance.should_not_receive(:save)\r
466         @op.store('bindata', @artist)\r
467       end
468       it '全体エラーメッセージがセットされている' do
469         lambda {
470           @op.store('bindata', @artist)\r
471         }.should change(@op.errors[:base], :count)
472       end
473     end
474   end
475 end