OSDN Git Service

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