OSDN Git Service

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