OSDN Git Service

t30350#:fix destroy
[pettanr/pettanr.git] / spec / models / picture_spec.rb
1 # -*- encoding: utf-8 -*-
2 #実素材
3 require 'spec_helper'
4
5 describe Picture do
6   before do
7     @admin = FactoryGirl.create :admin
8     @user = FactoryGirl.create( :user_yas)
9     @author = FactoryGirl.create :author, :user_id => @user.id
10     @artist = FactoryGirl.create :artist_yas, :author_id => @author.id
11     @other_user = FactoryGirl.create( :user_yas)
12     @other_author = FactoryGirl.create :author, :user_id => @other_user.id
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     @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
18   end
19   
20   describe '検証に於いて' do
21     before do
22       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
23     end
24     
25     context 'オーソドックスなデータのとき' do
26       it '下限データが通る' do
27         @p.revision = 1
28         @p.ext = 'png' #リストにない拡張子は通らないし
29         @p.width = 1
30         @p.height = 1
31         @p.filesize = 1
32         @p.md5 = 'a'*32
33         @p.classname = 'a'*1
34         @p.should be_valid
35       end
36       it '上限データが通る' do
37         @p.revision = 99999
38         @p.ext = 'jpeg'
39         @p.width = 99999
40         @p.height = 99999
41         @p.filesize = 2000000
42         @p.md5 = 'a'*32
43         @p.classname = 'a'*50
44         @p.should be_valid
45       end
46     end
47     
48     context 'original_picture_idを検証するとき' do
49       it 'nullなら失敗する' do
50         @p.original_picture_id = nil
51         @p.should_not be_valid
52       end
53       it '数値でなければ失敗する' do
54         @p.original_picture_id = 'a'
55         @p.should_not be_valid
56       end
57       it '存在する原画でなければ失敗する' do
58         @p.original_picture_id = 0
59         @p.should_not be_valid
60       end
61     end
62     context 'revisionを検証するとき' do
63       it 'nullなら失敗する' do
64         @p.revision = nil
65         @p.should_not be_valid
66       end
67       it '数値でなければ失敗する' do
68         @p.revision = 'a'
69         @p.should_not be_valid
70       end
71     end
72     context 'extを検証するとき' do
73       it 'nullなら失敗する' do
74         @p.ext = ''
75         @p.should_not be_valid
76       end
77       it '5文字以上なら失敗する' do
78         @p.ext = 'a'*5
79         @p.should_not be_valid
80       end
81       it 'png,gif,jpeg以外なら失敗する' do
82         @p.ext = 'bmp'
83         @p.should_not be_valid
84       end
85     end
86     context 'widthを検証するとき' do
87       it 'nullなら失敗する' do
88         @p.width = nil
89         @p.should_not be_valid
90       end
91       it '数値でなければ失敗する' do
92         @p.width = 'a'
93         @p.should_not be_valid
94       end
95       it '0なら失敗する' do
96         @p.width = '0'
97         @p.should_not be_valid
98       end
99       it '負でも失敗する' do
100         @p.width = -1
101         @p.should_not be_valid
102       end
103     end
104     context 'heightを検証するとき' do
105       it 'nullなら失敗する' do
106         @p.height = nil
107         @p.should_not be_valid
108       end
109       it '数値でなければ失敗する' do
110         @p.height = 'a'
111         @p.should_not be_valid
112       end
113       it '0なら失敗する' do
114         @p.height = '0'
115         @p.should_not be_valid
116       end
117       it '負でも失敗する' do
118         @p.height = -1
119         @p.should_not be_valid
120       end
121     end
122     context 'filesizeを検証するとき' do
123       it 'nullなら失敗する' do
124         @p.filesize = nil
125         @p.should_not be_valid
126       end
127       it '数値でなければ失敗する' do
128         @p.filesize = 'a'
129         @p.should_not be_valid
130       end
131       it '負なら失敗する' do
132         @p.filesize = '-1'
133         @p.should_not be_valid
134       end
135       it '2MB以上なら失敗する' do
136         @p.filesize = 2000000+1
137         @p.should_not be_valid
138       end
139     end
140     context 'md5を検証するとき' do
141       it 'nullなら失敗する' do
142         @p.md5 = ''
143         @p.should_not be_valid
144       end
145       it '31文字なら失敗する' do
146         @p.md5 = 'a'*31
147         @p.should_not be_valid
148       end
149       it '32文字以上なら失敗する' do
150         @p.md5 = 'a'*33
151         @p.should_not be_valid
152       end
153     end
154     context 'artist_idを検証するとき' do
155       it 'nullなら失敗する' do
156         @p.artist_id = nil
157         @p.should_not be_valid
158       end
159       it '数値でなければ失敗する' do
160         @p.artist_id = 'a'
161         @p.should_not be_valid
162       end
163       it '存在する絵師でなければ失敗する' do
164         @p.artist_id = 0
165         @p.should_not be_valid
166       end
167     end
168     context 'license_idを検証するとき' do
169       it 'nullなら失敗する' do
170         @p.license_id = nil
171         @p.should_not be_valid
172       end
173       it '数値でなければ失敗する' do
174         @p.license_id = 'a'
175         @p.should_not be_valid
176       end
177       it '存在するライセンスでなければ失敗する' do
178         @p.license_id = 0
179         @p.should_not be_valid
180       end
181     end
182     context 'artist_nameを検証するとき' do
183       it 'nullなら失敗する' do
184         @p.artist_name = nil
185         @p.should_not be_valid
186       end
187     end
188     context 'classnameを検証するとき' do
189       it 'nullなら失敗する' do
190         @p.classname = ''
191         @p.should_not be_valid
192       end
193       it '51文字以上なら失敗する' do
194         @p.classname = 'a'*51
195         @p.should_not be_valid
196       end
197     end
198     context 'creditを検証するとき' do
199     end
200     context 'settingsを検証するとき' do
201     end
202   end
203   
204   describe 'デフォルト値補充に於いて' do
205     it 'defined' do
206       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
207       @p.supply_default
208     end
209   end
210   
211   describe '上書き補充に於いて' do
212     before do
213       attr = {:ext => 'jpeg', :width => 264, :height => 265, :filesize => 266, 
214         :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, 
215         :artist_name => 'tester', :classname => 'Tester', :credit => {:title => 'cap'}.to_json.to_s, :settings => {:set => 1}.to_json.to_s}
216       @rp = FactoryGirl.build :resource_picture, attr
217       @p = FactoryGirl.build :picture, :original_picture_id => nil, :license_id => nil, :artist_id => nil, :revision => nil
218     end
219     it 'width, height, ext, filesize, md5, original_picture_idが設定されている' do
220       @p.overwrite @rp
221       @p.width.should eq 264
222       @p.height.should eq 265
223       @p.ext.should eq 'jpeg'
224       @p.filesize.should eq 266
225       @p.md5.should eq @rp.md5
226       @p.original_picture_id.should eq @op.id
227     end
228     it 'license_id, artist_id, artist_name, classname, credit, settingsが設定されている' do
229       @p.overwrite @rp
230       @p.license_id.should eq @license.id
231       @p.artist_id.should eq @artist.id
232       @p.artist_name.should eq 'tester'
233       @p.classname.should eq 'Tester'
234       @p.credit.should match /title/
235       @p.settings.should match /set/
236     end
237     it 'new_revisionに問い合わせている' do
238       Picture.any_instance.stub(:new_revision).with(any_args).and_return(3)
239       Picture.any_instance.should_receive(:new_revision).with(any_args).exactly(1)
240       @p.overwrite @rp
241     end
242     it 'revisionは、new_revisionに設定されている' do
243       Picture.any_instance.stub(:new_revision).with(any_args).and_return(3)
244       @p.overwrite @rp
245       @p.revision.should eq 3
246     end
247   end
248   
249   describe '所持判定に於いて' do
250     before do
251       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
252     end
253     context 'パラメータが作家のとき' do
254       it '自作の実素材ならyes' do
255         @p.own?(@author).should == true
256       end
257       it '他人のならno' do
258         @p.own?(@other_author).should == false
259       end
260     end
261     context 'パラメータが絵師のとき' do
262       it '自作の実素材ならyes' do
263         @p.own?(@artist).should == true
264       end
265       it '他人のならno' do
266         @p.own?(@other_artist).should == false
267       end
268     end
269     context 'それ以外のとき' do
270       it 'no' do
271         @p.own?(nil).should == false
272       end
273     end
274   end
275   describe '閲覧許可に於いて' do
276     before do
277       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
278     end
279     it 'Trueを返す。' do
280       r = @p.visible?(@artist)
281       r.should be_true
282     end
283   end
284   
285   describe '詳細閲覧許可に於いて' do
286     before do
287       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
288     end
289     it '自作の実素材ならyes' do
290       Picture.any_instance.stub(:own?).with(any_args).and_return(true)
291       @p.showable?(@artist).should == true
292     end
293     context '他人の実素材のとき' do
294       before do
295         Picture.any_instance.stub(:own?).with(any_args).and_return(false)
296       end
297       it '自身にhead判定と有効性判定を問い合わせ、両者がTrueならTrueを返す。' do
298         Picture.any_instance.stub(:head?).with(any_args).and_return(true)
299         Picture.any_instance.stub(:enable?).with(any_args).and_return(true)
300         r = @p.showable?(@author)
301         r.should be_true
302       end
303       it 'head判定がFalseならFalseを返す。' do
304         Picture.any_instance.stub(:head?).with(any_args).and_return(false)
305         Picture.any_instance.stub(:enable?).with(any_args).and_return(true)
306         r = @p.showable?(@author)
307         r.should be_false
308       end
309       it '有効性判定がFalseならFalseを返す。' do
310         Picture.any_instance.stub(:enable?).with(any_args).and_return(false)
311         Picture.any_instance.stub(:head?).with(any_args).and_return(true)
312         r = @p.showable?(@author)
313         r.should be_false
314       end
315     end
316   end
317   
318   describe 'ファイル名に於いて' do
319     before do
320       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
321     end
322     it 'id+拡張子のフォーマットで返す' do
323       r = @p.filename
324       r.should eq "#{@p.id}.png"
325     end
326   end
327   
328   describe 'gifファイル名に於いて' do
329     before do
330       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'gif'
331     end
332     it 'id.gifのフォーマットで返す' do
333       r = @p.filename
334       r.should eq "#{@p.id}.gif"
335     end
336   end
337   
338   describe 'MimeTypeに於いて' do
339     before do
340       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
341     end
342     it 'image/拡張子のフォーマットで返す' do
343       r = @p.mime_type
344       r.should eq "image/png"
345     end
346   end
347   
348   describe 'ファイルのurlに於いて' do
349     before do
350       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
351       Picture.any_instance.stub(:filename).and_return('3.gif')
352     end
353     it 'ファイル名取得を依頼している' do
354       Picture.any_instance.should_receive(:filename).exactly(1)
355       @p.url
356     end
357     it '/pictures/3.gifのフォーマットで返す' do
358       r = @p.url
359       r.should eq "/pictures/3.gif"
360     end
361   end
362   
363   describe '最新Revision取得に於いて' do
364     context '初めての原画を公開したとき' do
365       before do
366         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id
367       end
368       it 'Revisionは1となる' do
369         @p.new_revision.should eq 1
370       end
371     end
372     context 'HEADが1のとき' do
373       before do
374         FactoryGirl.create :picture, :revision => 1, :original_picture_id => @op.id, :license_id => @license.id
375         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id
376       end
377       it 'Revisionは2となる' do
378         @p.new_revision.should eq 2
379       end
380     end
381     context 'HEADが5のとき' do
382       before do
383         FactoryGirl.create :picture, :revision => 1, :original_picture_id => @op.id, :license_id => @license.id
384         FactoryGirl.create :picture, :revision => 5, :original_picture_id => @op.id, :license_id => @license.id
385         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id
386       end
387       it 'Revisionは6となる' do
388         @p.new_revision.should eq 6
389       end
390     end
391   end
392   
393   describe '有効性判定に於いて' do
394     before do
395       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id 
396       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
397       Picture.any_instance.stub(:head).and_return(@p)
398     end
399     context '自身のheadとリンクした素材があるとき' do
400       before do
401         Picture.any_instance.stub(:resource_picture).and_return(@rp)
402       end
403       it 'trueを返す' do
404         res = @p.enable?
405         res.should be_true
406       end
407     end
408     context '自身のheadとリンクした素材がないとき' do
409       before do
410         Picture.any_instance.stub(:resource_picture).and_return(nil)
411       end
412       it 'falseを返す' do
413         res = @p.enable?
414         res.should be_false
415       end
416     end
417   end
418   
419   describe 'head取得に於いて' do
420     before do
421       #旧版
422       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
423       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
424         :original_picture_id => @op.id, :md5 => 'a' * 32
425       #最新版
426       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
427         :original_picture_id => @op.id, :md5 => 'b' * 32
428       #除外すべき無関係画像
429       @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
430       @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
431         :original_picture_id => @op2.id, :md5 => 'C' * 32
432     end
433     context 'つつがなく終わるとき' do
434       before do
435         #素材は有効
436         @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p2.id
437       end
438       it '最新版を返す' do
439         res = @p.head
440         res.should eq @p2
441       end
442     end
443     context '無効な素材(素材とリンクしてない)とき' do
444       it '同じく最新版を返す' do
445         res = @p.head
446         res.should eq @p2
447       end
448     end
449   end
450   
451   describe 'head判定に於いて' do
452     before do
453       #旧版
454       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
455       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
456         :original_picture_id => @op.id, :md5 => 'a' * 32
457       #最新版
458       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
459         :original_picture_id => @op.id, :md5 => 'b' * 32
460       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p2.id
461     end
462     context '旧版のとき' do
463       it 'falseを返す' do
464         res = @p.head?
465         res.should be_false
466       end
467     end
468     context '最新版のとき' do
469       it 'trueを返す' do
470         res = @p2.head?
471         res.should be_true
472       end
473     end
474   end
475   
476   describe 'フォーマット変換対象判定に於いて' do
477     before do
478       @p = FactoryGirl.build :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id
479     end
480     context '変換するケース' do
481       it '画像フォーマットがpngかつライセンスの変換禁止フラグが無効のときTrue' do
482         Picture.any_instance.stub(:flag_gif_convert).with(any_args).and_return(0)
483         @p.ext = 'png'
484         @p.to_gif?.should be_true
485       end
486     end
487     context '変換しないケース' do
488       it '画像フォーマットがpngでない' do
489         Picture.any_instance.stub(:flag_gif_convert).with(any_args).and_return(0)
490         @p.ext = 'gif'
491         @p.to_gif?.should be_false
492       end
493       it '変換禁止フラグが無効' do
494         Picture.any_instance.stub(:flag_gif_convert).with(any_args).and_return(-1)
495         @p.ext = 'png'
496         @p.to_gif?.should be_false
497       end
498     end
499   end
500   
501   describe 'サブディレクトリリストに於いて' do
502     before do
503       @p = FactoryGirl.build :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id
504     end
505     it '配列で返す' do
506       Picture.any_instance.stub(:flag_gif_convert).with(any_args).and_return(0)
507       r = @p.subdirs
508       r.is_a?(Array).should be_true
509     end
510     it '本画像(ベースディレクトリ)を含んでいる' do
511       Picture.any_instance.stub(:flag_reverse).with(any_args).and_return(0)
512       r = @p.subdirs
513       r.include?('').should be_true
514     end
515     context '反転が許可されているとき' do
516       it '垂直・水平・垂直水平反転ディレクトリも返す' do
517         Picture.any_instance.stub(:flag_reverse).with(any_args).and_return(0)
518         r = @p.subdirs
519         r.include?('v').should be_true
520         r.include?('h').should be_true
521         r.include?('vh').should be_true
522       end
523     end
524     context '反転が許可されていないとき' do
525       it '本画像(ベースディレクトリ)だけを返す' do
526         Picture.any_instance.stub(:flag_reverse).with(any_args).and_return(-1)
527         r = @p.subdirs
528         r.size.should eq 1
529       end
530     end
531   end
532   
533   describe 'md5重複リストに於いて' do
534     before do
535       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
536       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
537         :original_picture_id => @op.id, :md5 => 'a' * 32
538       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
539       @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
540       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
541         :original_picture_id => @op2.id, :md5 => 'b' * 32
542       @op3 = FactoryGirl.create :original_picture, :artist_id => @artist.id
543     end
544     context '除外する原画idで指定されていないとき' do
545       it 'リストを返す' do
546         res = Picture.list_by_md5(@p.md5)
547         res.is_a?(Array).should be_true
548       end
549       it 'md5が違えば含まない' do
550         res = Picture.list_by_md5(@p.md5)
551         res.include?(@p2).should be_false
552       end
553       it '更新日時順' do
554         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
555           :original_picture_id => @op2.id, :md5 => 'C' * 32
556         @p4 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
557           :original_picture_id => @op3.id, :md5 => @p3.md5, :updated_at => Time.now + 100
558         res = Picture.find_by_md5(@p3.md5)
559         res.should eq [@p4, @p3]
560       end
561     end
562     context '除外する原画idで指定されたとき' do
563       it 'リストを返す' do
564         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
565         res.is_a?(Array).should be_true
566       end
567       it 'md5が違えば含まない' do
568         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
569         res.include?(@p2).should be_false
570       end
571       it '同一原画は含まない' do
572         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
573         res.empty?.should be_true
574       end
575       it '同一原画は旧版でも含まない' do
576         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
577           :original_picture_id => @op.id, :md5 => 'a' * 32
578         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
579         res.empty?.should be_true
580       end
581       it '他所の原画なら含む' do
582         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
583           :original_picture_id => @op2.id, :md5 => 'a' * 32
584         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
585         res.should eq [@p3]
586       end
587       it '他所の原画でもmd5が違えば含まない' do
588         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
589           :original_picture_id => @op2.id, :md5 => 'c' * 32
590         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
591         res.empty?.should be_true
592       end
593       it '更新日時順' do
594         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
595           :original_picture_id => @op2.id, :md5 => 'a' * 32
596         @p4 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
597           :original_picture_id => @op3.id, :md5 => 'a' * 32, :updated_at => Time.now + 100
598         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
599         res.should eq [@p4, @p3]
600       end
601     end
602   end
603   
604   describe 'md5重複判定に於いて' do
605     before do
606       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
607       @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
608       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 0
609       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
610     end
611     context '同一原画以外に同じ値があるとき' do
612       before do
613         @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op2.id, :license_id => @license.id
614       end
615       it 'trueを返す' do
616         res = Picture.exist_by_md5(@p.md5, @p.original_picture_id)
617         res.should be_true
618       end
619     end
620     context '同一原画以外に同じ値がないとき' do
621       it 'falseを返す' do
622         res = Picture.exist_by_md5(@p.md5, @p.original_picture_id)
623         res.should be_false
624       end
625     end
626     context '同一原画に同じ値があるとき' do
627       before do
628         @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 1
629       end
630       it 'falseを返す' do
631         res = Picture.exist_by_md5(@p.md5, @p.original_picture_id)
632         res.should be_false
633       end
634     end
635   end
636   
637   describe '単体取得に於いて' do
638     before do
639       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
640     end
641     context 'つつがなく終わるとき' do
642       it '閲覧許可を問い合わせている' do
643         Picture.any_instance.stub(:visible?).with(any_args).and_return(true)
644         Picture.any_instance.should_receive(:visible?).with(any_args).exactly(1)
645         r = Picture.show @p.id, @author
646       end
647     end
648     it '指定の実素材を返す' do
649       r = Picture.show @p.id, @author
650       r.should eq @p
651     end
652     context '他人の実素材を開こうとしたとき' do
653       it '403Forbidden例外を返す' do
654         Picture.any_instance.stub(:visible?).and_return(false)
655         lambda{
656           r = Picture.show @p.id, @other_author
657         }.should raise_error(ActiveRecord::Forbidden)
658       end
659     end
660     context '存在しない実素材を開こうとしたとき' do
661       it '404RecordNotFound例外を返す' do
662         lambda{
663           r = Picture.show 0, @author
664         }.should raise_error(ActiveRecord::RecordNotFound)
665       end
666     end
667   end
668   
669   describe '作成に於いて' do
670     before do
671       @imager = ImagerTest.load "abc\ndef\nghi"
672       #原画ファイル削除だけは必ず成功するものとしておく
673       PictureIO::LocalPicture.any_instance.stub(:delete).with(any_args).and_return(true)
674     end
675     context '事前チェック' do
676       before do
677         #すべての処理が正常パターンで通過すれば、一番深い分岐まで通る。
678         #それで外部のメソッド呼び出しだけに着目してテストする。
679         Picture.any_instance.stub(:save).with(any_args).and_return(true)
680         Picture.any_instance.stub(:store_picture).with(any_args).and_return(true)
681         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true)
682         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
683       end
684       it '自身を保存している' do
685         Picture.any_instance.should_receive(:save).with(any_args).exactly(1)
686         r = @p.store(@imager)
687       end
688       it '画像ファイルの作成機能で画像を保存している' do
689         Picture.any_instance.stub(:filename).with(any_args).and_return('1.png')
690         #二回目の保存はgif変換の結果を渡す。
691         Picture.any_instance.should_receive(:store_picture).with(any_args).exactly(2)
692         r = @p.store(@imager)
693       end
694       it '自身にgifフォーマット変換対象かを問い合わせている' do
695         Picture.any_instance.should_receive(:to_gif?).with(any_args).exactly(1)
696         r = @p.store(@imager)
697       end
698     end
699     context 'つつがなく終わるとき' do
700       before do
701         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
702         Picture.any_instance.stub(:store_picture).with(any_args).and_return(true)
703         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true)
704         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
705       end
706       it 'Trueを返す' do
707         r = @p.store(@imager)
708         r.should be_true
709       end
710       it '自身が保存されている' do
711         lambda {
712           r = @p.store(@imager)
713         }.should change Picture, :count
714       end
715     end
716     context 'gif変換なしで、つつがなく終わるとき' do
717       before do
718         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
719         Picture.any_instance.stub(:store_picture).with(any_args).and_return(true)
720         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(false)
721         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
722       end
723       it 'Trueを返す' do
724         r = @p.store(@imager)
725         r.should be_true
726       end
727       it 'gif保存は呼ばれていない' do
728         #二回目の画像作成が呼び出されないで1回こっきりならgif保存は呼ばれていないんだろう。
729         Picture.any_instance.should_receive(:store_picture).with(any_args).exactly(1)
730         r = @p.store(@imager)
731       end
732     end
733     #以下から例外ケース。処理先頭から失敗させていく
734     context '自身の保存に失敗したとき' do
735       before do
736         Picture.any_instance.stub(:save).with(any_args).and_return(false)
737         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
738       end
739       it 'Falseを返す' do
740         r = @p.store(@imager)
741         r.should be_false
742       end
743       it '更新されていない' do
744         r = @p.store(@imager)
745         @p.should be_a_new Picture
746       end
747     end
748     context '画像の保存に失敗したとき' do
749       before do
750         Picture.any_instance.stub(:store_picture).with(any_args).and_return(false)
751         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
752       end
753       it 'Falseを返す' do
754         r = @p.store(@imager)
755         r.should be_false
756       end
757       it 'gif変換判定は呼ばれていない' do
758         Picture.any_instance.should_not_receive(:to_gif?).with(any_args).exactly(0)
759         r = @p.store(@imager)
760       end
761     end
762     context 'gif変換に失敗したとき' do
763       before do
764         Picture.any_instance.stub(:store_picture).with(any_args).and_return(true)
765         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true)
766         ImagerTest.stub(:load).with(any_args).and_return(false)
767         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
768       end
769       it 'Falseを返す' do
770         r = @p.store(@imager)
771         r.should be_false
772       end
773       it 'gif画像の保存は呼ばれていない' do
774         #本画像の保存があるので、一度は呼ばれる
775         Picture.any_instance.should_receive(:store_picture).with(any_args).exactly(1)
776         r = @p.store(@imager)
777       end
778     end
779     context 'gif画像の保存に失敗したとき' do
780       before do
781         @gifimager = @imager.to_gif
782         ImagerTest.any_instance.stub(:to_gif).with(any_args).and_return(@gifimager)
783         Picture.any_instance.stub(:filename).with(any_args).and_return('1.png')
784         Picture.any_instance.stub(:gifname).with(any_args).and_return('1.gif')
785         Picture.any_instance.stub(:store_picture).with(@imager, '1.png').and_return(true)
786         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true)
787         Picture.any_instance.stub(:store_picture).with(@gifimager, '1.gif').and_return(false)
788         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
789       end
790       it 'Falseを返す' do
791         r = @p.store(@imager)
792         r.should be_false
793       end
794     end
795   end
796   
797   describe '画像ファイルの作成に於いて' do
798     #PictureIo経由で画像を保存するための機能。ファイル名に自身のidを使うので事前に自身の保存が必要。
799     before do
800       @imager = ImagerTest.load "abc\ndef\nghi"
801       #原画ファイル削除だけは必ず成功するものとしておく
802       PictureIO::LocalPicture.any_instance.stub(:delete).with(any_args).and_return(true)
803       
804       Picture.any_instance.stub(:subdirs).with(any_args).and_return(['', 'v', 'h', 'vh'])
805       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
806     end
807     context '事前チェック' do
808       before do
809         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
810         PictureIO.picture_io.stub(:put).with(any_args).and_return(true)
811       end
812       it '画像ファイルの保存が4回呼ばれる' do
813         PictureIO.picture_io.should_receive(:put).with(any_args).exactly(4)
814         r = @p.store_picture(@imager, '1.png')
815       end
816       it '画像ファイルのベースへの保存が1回呼ばれる' do
817         PictureIO.picture_io.should_receive(:put).with("abc\ndef\nghi", '1.png', '').exactly(1)
818         r = @p.store_picture(@imager, '1.png')
819       end
820       it '画像ファイルの垂直反転への保存が1回呼ばれる' do
821         PictureIO.picture_io.should_receive(:put).with("cba\nfed\nihg", '1.png', 'v').exactly(1)
822         r = @p.store_picture(@imager, '1.png')
823       end
824       it '画像ファイルの水平反転への保存が1回呼ばれる' do
825         PictureIO.picture_io.should_receive(:put).with("ghi\ndef\nabc", '1.png', 'h').exactly(1)
826         r = @p.store_picture(@imager, '1.png')
827       end
828       it '画像ファイルの垂直水平反転への保存が1回呼ばれる' do
829         PictureIO.picture_io.should_receive(:put).with("ihg\nfed\ncba", '1.png', 'vh').exactly(1)
830         r = @p.store_picture(@imager, '1.png')
831       end
832     end
833     context 'つつがなく終わるとき' do
834       before do
835         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
836         PictureIO.picture_io.stub(:put).with(any_args).and_return(true)
837       end
838       it 'Trueを返す' do
839         r = @p.store_picture(@imager, '1.png')
840         r.should be_true
841       end
842     end
843     context '例外ケース' do
844       before do
845         PictureIO.picture_io.stub(:put).with(any_args).and_return(false)
846       end
847       it 'Falseを返す' do
848         r = @p.store_picture(@imager, '1.png')
849         r.should be_false
850       end
851     end
852     
853   end
854   
855   describe 'フラグ展開に於いて' do
856     before do
857       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id,
858         :settings => "{\"open\": 1, \"commercial\": 2, \"official\": 3, \"attribution\": 4, \"derive\": 5, \"thumbnail\": 6, \"gif_convert\": 7, \"reverse\": 8, \"resize\": 9, \"sync_vh\": 10, \"overlap\": 11}"
859     end
860     context 'json展開チェック' do
861       it '展開してなければ展開して@flagsに保管する' do
862         @p.flags.should_not be_nil
863       end
864       it '展開できなければ{}' do
865         @p.settings += '}'
866         @p.flags.is_a?(Hash).should be_true
867         @p.flags.empty?.should be_true
868       end
869     end
870     context 'openについて' do
871       it '@flag_openに保管する' do
872         @p.flag_open.should_not be_nil
873       end
874       it '本当にフラグHashからじゃなく、変数から取得してる?' do
875         @p.flag_open
876         @p.flags = nil
877         @p.flag_open.should_not be_nil
878       end
879       it '1を返す' do
880         @p.flag_open.should eq 1
881       end
882     end
883     context 'commercialについて' do
884       it '@flag_commercialに保管する' do
885         @p.flag_commercial.should_not be_nil
886       end
887       it '本当にフラグHashからじゃなく、変数から取得してる?' do
888         @p.flag_commercial
889         @p.flags = nil
890         @p.flag_commercial.should_not be_nil
891       end
892       it '2を返す' do
893         @p.flag_commercial.should eq 2
894       end
895     end
896     context 'officialについて' do
897       it '@flag_officialに保管する' do
898         @p.flag_official.should_not be_nil
899       end
900       it '本当にフラグHashからじゃなく、変数から取得してる?' do
901         @p.flag_official
902         @p.flags = nil
903         @p.flag_official.should_not be_nil
904       end
905       it 'を返す' do
906         @p.flag_official.should eq 3
907       end
908     end
909     context 'attributionについて' do
910       it '@flag_attributionに保管する' do
911         @p.flag_attribution.should_not be_nil
912       end
913       it '本当にフラグHashからじゃなく、変数から取得してる?' do
914         @p.flag_attribution
915         @p.flags = nil
916         @p.flag_attribution.should_not be_nil
917       end
918       it '4を返す' do
919         @p.flag_attribution.should eq 4
920       end
921     end
922     context 'deriveについて' do
923       it '@flag_deriveに保管する' do
924         @p.flag_derive.should_not be_nil
925       end
926       it '本当にフラグHashからじゃなく、変数から取得してる?' do
927         @p.flag_derive
928         @p.flags = nil
929         @p.flag_derive.should_not be_nil
930       end
931       it '5を返す' do
932         @p.flag_derive.should eq 5
933       end
934     end
935     context 'thumbnailについて' do
936       it '@flag_thumbnailに保管する' do
937         @p.flag_thumbnail.should_not be_nil
938       end
939       it '本当にフラグHashからじゃなく、変数から取得してる?' do
940         @p.flag_thumbnail
941         @p.flags = nil
942         @p.flag_thumbnail.should_not be_nil
943       end
944       it '6を返す' do
945         @p.flag_thumbnail.should eq 6
946       end
947     end
948     context 'gif_convertについて' do
949       it '@flag_gif_convertに保管する' do
950         @p.flag_gif_convert.should_not be_nil
951       end
952       it '本当にフラグHashからじゃなく、変数から取得してる?' do
953         @p.flag_gif_convert
954         @p.flags = nil
955         @p.flag_gif_convert.should_not be_nil
956       end
957       it '7を返す' do
958         @p.flag_gif_convert.should eq 7
959       end
960     end
961     context 'reverseについて' do
962       it '@flag_reverseに保管する' do
963         @p.flag_reverse.should_not be_nil
964       end
965       it '本当にフラグHashからじゃなく、変数から取得してる?' do
966         @p.flag_reverse
967         @p.flags = nil
968         @p.flag_reverse.should_not be_nil
969       end
970       it '8を返す' do
971         @p.flag_reverse.should eq 8
972       end
973     end
974     context 'resizeについて' do
975       it '@flag_resizeに保管する' do
976         @p.flag_resize.should_not be_nil
977       end
978       it '本当にフラグHashからじゃなく、変数から取得してる?' do
979         @p.flag_resize
980         @p.flags = nil
981         @p.flag_resize.should_not be_nil
982       end
983       it '9を返す' do
984         @p.flag_resize.should eq 9
985       end
986     end
987     context 'sync_vhについて' do
988       it '@flag_sync_vhに保管する' do
989         @p.flag_sync_vh.should_not be_nil
990       end
991       it '本当にフラグHashからじゃなく、変数から取得してる?' do
992         @p.flag_sync_vh
993         @p.flags = nil
994         @p.flag_sync_vh.should_not be_nil
995       end
996       it '10を返す' do
997         @p.flag_sync_vh.should eq 10
998       end
999     end
1000     context 'overlapについて' do
1001       it '@flag_overlapに保管する' do
1002         @p.flag_overlap.should_not be_nil
1003       end
1004       it '本当にフラグHashからじゃなく、変数から取得してる?' do
1005         @p.flag_overlap
1006         @p.flags = nil
1007         @p.flag_overlap.should_not be_nil
1008       end
1009       it '11を返す' do
1010         @p.flag_overlap.should eq 11
1011       end
1012     end
1013   end
1014
1015   describe 'クレジットデータに於いて' do
1016     before do
1017       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
1018       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :credit => '{"system_picture_id": 2}'
1019     end
1020     it 'system_picture_idが入っている' do
1021       res = @p.credit_data
1022       res["system_picture_id"].should eq 2
1023     end
1024   end
1025   
1026 end