OSDN Git Service

t#30328:create op import ...and pull
[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     context '自身に原画がリンクしていないとき' do
290       before do
291         Picture.any_instance.stub(:original_picture).with(any_args).and_return(nil)
292       end
293       it 'Falseを返す' do
294         r = @p.showable?(@author)
295         r.should be_false
296       end
297     end
298     it '自作の実素材ならyes' do
299       Picture.any_instance.stub(:own?).with(any_args).and_return(true)
300       @p.showable?(@artist).should == true
301     end
302     context '他人の実素材のとき' do
303       before do
304         Picture.any_instance.stub(:own?).with(any_args).and_return(false)
305       end
306       it '自身にhead判定と有効性判定を問い合わせ、両者がTrueならTrueを返す。' do
307         Picture.any_instance.stub(:head?).with(any_args).and_return(true)
308         Picture.any_instance.stub(:enable?).with(any_args).and_return(true)
309         r = @p.showable?(@author)
310         r.should be_true
311       end
312       it 'head判定がFalseならFalseを返す。' do
313         Picture.any_instance.stub(:head?).with(any_args).and_return(false)
314         Picture.any_instance.stub(:enable?).with(any_args).and_return(true)
315         r = @p.showable?(@author)
316         r.should be_false
317       end
318       it '有効性判定がFalseならFalseを返す。' do
319         Picture.any_instance.stub(:enable?).with(any_args).and_return(false)
320         Picture.any_instance.stub(:head?).with(any_args).and_return(true)
321         r = @p.showable?(@author)
322         r.should be_false
323       end
324     end
325   end
326   
327   describe 'ファイル名に於いて' do
328     before do
329       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
330     end
331     it 'id+拡張子のフォーマットで返す' do
332       r = @p.filename
333       r.should eq "#{@p.id}.png"
334     end
335   end
336   
337   describe 'gifファイル名に於いて' do
338     before do
339       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'gif'
340     end
341     it 'id.gifのフォーマットで返す' do
342       r = @p.filename
343       r.should eq "#{@p.id}.gif"
344     end
345   end
346   
347   describe 'MimeTypeに於いて' do
348     before do
349       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
350     end
351     it 'image/拡張子のフォーマットで返す' do
352       r = @p.mime_type
353       r.should eq "image/png"
354     end
355   end
356   
357   describe 'ファイルのurlに於いて' do
358     before do
359       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
360       Picture.any_instance.stub(:filename).and_return('3.gif')
361     end
362     it 'ファイル名取得を依頼している' do
363       Picture.any_instance.should_receive(:filename).exactly(1)
364       @p.url
365     end
366     it '/pictures/3.gifのフォーマットで返す' do
367       r = @p.url
368       r.should eq "/pictures/3.gif"
369     end
370   end
371   
372   describe '最新Revision取得に於いて' do
373     context '初めての原画を公開したとき' do
374       before do
375         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id
376       end
377       it 'Revisionは1となる' do
378         @p.new_revision.should eq 1
379       end
380     end
381     context 'HEADが1のとき' do
382       before do
383         FactoryGirl.create :picture, :revision => 1, :original_picture_id => @op.id, :license_id => @license.id
384         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id
385       end
386       it 'Revisionは2となる' do
387         @p.new_revision.should eq 2
388       end
389     end
390     context 'HEADが5のとき' do
391       before do
392         FactoryGirl.create :picture, :revision => 1, :original_picture_id => @op.id, :license_id => @license.id
393         FactoryGirl.create :picture, :revision => 5, :original_picture_id => @op.id, :license_id => @license.id
394         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id
395       end
396       it 'Revisionは6となる' do
397         @p.new_revision.should eq 6
398       end
399     end
400   end
401   
402   describe '有効性判定に於いて' do
403     before do
404       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id 
405       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
406       Picture.any_instance.stub(:head).and_return(@p)
407     end
408     context '自身のheadとリンクした素材があるとき' do
409       before do
410         Picture.any_instance.stub(:resource_picture).and_return(@rp)
411       end
412       it 'trueを返す' do
413         res = @p.enable?
414         res.should be_true
415       end
416     end
417     context '自身のheadとリンクした素材がないとき' do
418       before do
419         Picture.any_instance.stub(:resource_picture).and_return(nil)
420       end
421       it 'falseを返す' do
422         res = @p.enable?
423         res.should be_false
424       end
425     end
426   end
427   
428   describe 'head取得に於いて' do
429     before do
430       #旧版
431       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
432       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
433         :original_picture_id => @op.id, :md5 => 'a' * 32
434       #最新版
435       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
436         :original_picture_id => @op.id, :md5 => 'b' * 32
437       #除外すべき無関係画像
438       @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
439       @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
440         :original_picture_id => @op2.id, :md5 => 'C' * 32
441     end
442     context 'つつがなく終わるとき' do
443       before do
444         #素材は有効
445         @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p2.id
446       end
447       it '最新版を返す' do
448         res = @p.head
449         res.should eq @p2
450       end
451     end
452     context '無効な素材(素材とリンクしてない)とき' do
453       it '同じく最新版を返す' do
454         res = @p.head
455         res.should eq @p2
456       end
457     end
458   end
459   
460   describe 'head判定に於いて' do
461     before do
462       #旧版
463       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
464       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
465         :original_picture_id => @op.id, :md5 => 'a' * 32
466       #最新版
467       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
468         :original_picture_id => @op.id, :md5 => 'b' * 32
469       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p2.id
470     end
471     context '旧版のとき' do
472       it 'falseを返す' do
473         res = @p.head?
474         res.should be_false
475       end
476     end
477     context '最新版のとき' do
478       it 'trueを返す' do
479         res = @p2.head?
480         res.should be_true
481       end
482     end
483   end
484   
485   describe 'フォーマット変換対象判定に於いて' do
486     before do
487       @p = FactoryGirl.build :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id
488     end
489     context '変換するケース' do
490       it '画像フォーマットがpngかつライセンスの変換禁止フラグが無効のときTrue' do
491         Picture.any_instance.stub(:flag_gif_convert).with(any_args).and_return(0)
492         @p.ext = 'png'
493         @p.to_gif?.should be_true
494       end
495     end
496     context '変換しないケース' do
497       it '画像フォーマットがpngでない' do
498         Picture.any_instance.stub(:flag_gif_convert).with(any_args).and_return(0)
499         @p.ext = 'gif'
500         @p.to_gif?.should be_false
501       end
502       it '変換禁止フラグが無効' do
503         Picture.any_instance.stub(:flag_gif_convert).with(any_args).and_return(-1)
504         @p.ext = 'png'
505         @p.to_gif?.should be_false
506       end
507     end
508   end
509   
510   describe 'サブディレクトリリストに於いて' do
511     before do
512       @p = FactoryGirl.build :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id
513     end
514     it '配列で返す' do
515       Picture.any_instance.stub(:flag_gif_convert).with(any_args).and_return(0)
516       r = @p.subdirs
517       r.is_a?(Array).should be_true
518     end
519     it '本画像(ベースディレクトリ)を含んでいる' do
520       Picture.any_instance.stub(:flag_reverse).with(any_args).and_return(0)
521       r = @p.subdirs
522       r.include?('').should be_true
523     end
524     context '反転が許可されているとき' do
525       it '垂直・水平・垂直水平反転ディレクトリも返す' do
526         Picture.any_instance.stub(:flag_reverse).with(any_args).and_return(0)
527         r = @p.subdirs
528         r.include?('v').should be_true
529         r.include?('h').should be_true
530         r.include?('vh').should be_true
531       end
532     end
533     context '反転が許可されていないとき' do
534       it '本画像(ベースディレクトリ)だけを返す' do
535         Picture.any_instance.stub(:flag_reverse).with(any_args).and_return(-1)
536         r = @p.subdirs
537         r.size.should eq 1
538       end
539     end
540   end
541   
542   describe 'md5重複リストに於いて' do
543     before do
544       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
545       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
546         :original_picture_id => @op.id, :md5 => 'a' * 32
547       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
548       @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
549       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 0,
550         :original_picture_id => @op2.id, :md5 => 'b' * 32
551       @op3 = FactoryGirl.create :original_picture, :artist_id => @artist.id
552     end
553     context '除外する原画idで指定されていないとき' do
554       it 'リストを返す' do
555         res = Picture.list_by_md5(@p.md5)
556         res.is_a?(Array).should be_true
557       end
558       it 'md5が違えば含まない' do
559         res = Picture.list_by_md5(@p.md5)
560         res.include?(@p2).should be_false
561       end
562       it '更新日時順' do
563         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
564           :original_picture_id => @op2.id, :md5 => 'C' * 32
565         @p4 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
566           :original_picture_id => @op3.id, :md5 => @p3.md5, :updated_at => Time.now + 100
567         res = Picture.find_by_md5(@p3.md5)
568         res.should eq [@p4, @p3]
569       end
570     end
571     context '除外する原画idで指定されたとき' do
572       it 'リストを返す' do
573         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
574         res.is_a?(Array).should be_true
575       end
576       it 'md5が違えば含まない' do
577         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
578         res.include?(@p2).should be_false
579       end
580       it '同一原画は含まない' do
581         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
582         res.empty?.should be_true
583       end
584       it '同一原画は旧版でも含まない' do
585         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
586           :original_picture_id => @op.id, :md5 => 'a' * 32
587         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
588         res.empty?.should be_true
589       end
590       it '他所の原画なら含む' do
591         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
592           :original_picture_id => @op2.id, :md5 => 'a' * 32
593         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
594         res.should eq [@p3]
595       end
596       it '他所の原画でもmd5が違えば含まない' do
597         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
598           :original_picture_id => @op2.id, :md5 => 'c' * 32
599         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
600         res.empty?.should be_true
601       end
602       it '更新日時順' do
603         @p3 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
604           :original_picture_id => @op2.id, :md5 => 'a' * 32
605         @p4 = FactoryGirl.create :picture, :artist_id => @artist.id, :license_id => @license.id, :revision => 1,
606           :original_picture_id => @op3.id, :md5 => 'a' * 32, :updated_at => Time.now + 100
607         res = Picture.list_by_md5(@p.md5, @p.original_picture_id)
608         res.should eq [@p4, @p3]
609       end
610     end
611   end
612   
613   describe 'md5重複判定に於いて' do
614     before do
615       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
616       @op2 = FactoryGirl.create :original_picture, :artist_id => @artist.id
617       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 0
618       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
619     end
620     context '同一原画以外に同じ値があるとき' do
621       before do
622         @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op2.id, :license_id => @license.id
623       end
624       it 'trueを返す' do
625         res = Picture.exist_by_md5(@p.md5, @p.original_picture_id)
626         res.should be_true
627       end
628     end
629     context '同一原画以外に同じ値がないとき' do
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     context '同一原画に同じ値があるとき' do
636       before do
637         @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 1
638       end
639       it 'falseを返す' do
640         res = Picture.exist_by_md5(@p.md5, @p.original_picture_id)
641         res.should be_false
642       end
643     end
644   end
645   
646   describe '単体取得に於いて' do
647     before do
648       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id
649     end
650     context 'つつがなく終わるとき' do
651       it '閲覧許可を問い合わせている' do
652         Picture.any_instance.stub(:visible?).with(any_args).and_return(true)
653         Picture.any_instance.should_receive(:visible?).with(any_args).exactly(1)
654         r = Picture.show @p.id, @author
655       end
656     end
657     it '指定の実素材を返す' do
658       r = Picture.show @p.id, @author
659       r.should eq @p
660     end
661     context '他人の実素材を開こうとしたとき' do
662       it '403Forbidden例外を返す' do
663         Picture.any_instance.stub(:visible?).and_return(false)
664         lambda{
665           r = Picture.show @p.id, @other_author
666         }.should raise_error(ActiveRecord::Forbidden)
667       end
668     end
669     context '存在しない実素材を開こうとしたとき' do
670       it '404RecordNotFound例外を返す' do
671         lambda{
672           r = Picture.show 0, @author
673         }.should raise_error(ActiveRecord::RecordNotFound)
674       end
675     end
676   end
677   
678   describe '作成に於いて' do
679     before do
680       @imager = ImagerTest.load "abc\ndef\nghi"
681       #原画ファイル削除だけは必ず成功するものとしておく
682       PictureIO::LocalPicture.any_instance.stub(:delete).with(any_args).and_return(true)
683     end
684     context '事前チェック' do
685       before do
686         #すべての処理が正常パターンで通過すれば、一番深い分岐まで通る。
687         #それで外部のメソッド呼び出しだけに着目してテストする。
688         Picture.any_instance.stub(:save).with(any_args).and_return(true)
689         Picture.any_instance.stub(:store_picture).with(any_args).and_return(true)
690         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true)
691         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
692       end
693       it '自身を保存している' do
694         Picture.any_instance.should_receive(:save).with(any_args).exactly(1)
695         r = @p.store(@imager)
696       end
697       it '画像ファイルの作成機能で画像を保存している' do
698         Picture.any_instance.stub(:filename).with(any_args).and_return('1.png')
699         #二回目の保存はgif変換の結果を渡す。
700         Picture.any_instance.should_receive(:store_picture).with(any_args).exactly(2)
701         r = @p.store(@imager)
702       end
703       it '自身にgifフォーマット変換対象かを問い合わせている' do
704         Picture.any_instance.should_receive(:to_gif?).with(any_args).exactly(1)
705         r = @p.store(@imager)
706       end
707     end
708     context 'つつがなく終わるとき' do
709       before do
710         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
711         Picture.any_instance.stub(:store_picture).with(any_args).and_return(true)
712         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true)
713         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
714       end
715       it 'Trueを返す' do
716         r = @p.store(@imager)
717         r.should be_true
718       end
719       it '自身が保存されている' do
720         lambda {
721           r = @p.store(@imager)
722         }.should change Picture, :count
723       end
724     end
725     context 'gif変換なしで、つつがなく終わるとき' do
726       before do
727         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
728         Picture.any_instance.stub(:store_picture).with(any_args).and_return(true)
729         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(false)
730         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
731       end
732       it 'Trueを返す' do
733         r = @p.store(@imager)
734         r.should be_true
735       end
736       it 'gif保存は呼ばれていない' do
737         #二回目の画像作成が呼び出されないで1回こっきりならgif保存は呼ばれていないんだろう。
738         Picture.any_instance.should_receive(:store_picture).with(any_args).exactly(1)
739         r = @p.store(@imager)
740       end
741     end
742     #以下から例外ケース。処理先頭から失敗させていく
743     context '自身の保存に失敗したとき' do
744       before do
745         Picture.any_instance.stub(:save).with(any_args).and_return(false)
746         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
747       end
748       it 'Falseを返す' do
749         r = @p.store(@imager)
750         r.should be_false
751       end
752       it '更新されていない' do
753         r = @p.store(@imager)
754         @p.should be_a_new Picture
755       end
756     end
757     context '画像の保存に失敗したとき' do
758       before do
759         Picture.any_instance.stub(:store_picture).with(any_args).and_return(false)
760         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
761       end
762       it 'Falseを返す' do
763         r = @p.store(@imager)
764         r.should be_false
765       end
766       it 'gif変換判定は呼ばれていない' do
767         Picture.any_instance.should_not_receive(:to_gif?).with(any_args).exactly(0)
768         r = @p.store(@imager)
769       end
770     end
771     context 'gif変換に失敗したとき' do
772       before do
773         Picture.any_instance.stub(:store_picture).with(any_args).and_return(true)
774         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true)
775         ImagerTest.stub(:load).with(any_args).and_return(false)
776         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
777       end
778       it 'Falseを返す' do
779         r = @p.store(@imager)
780         r.should be_false
781       end
782       it 'gif画像の保存は呼ばれていない' do
783         #本画像の保存があるので、一度は呼ばれる
784         Picture.any_instance.should_receive(:store_picture).with(any_args).exactly(1)
785         r = @p.store(@imager)
786       end
787     end
788     context 'gif画像の保存に失敗したとき' do
789       before do
790         @gifimager = @imager.to_gif
791         ImagerTest.any_instance.stub(:to_gif).with(any_args).and_return(@gifimager)
792         Picture.any_instance.stub(:filename).with(any_args).and_return('1.png')
793         Picture.any_instance.stub(:gifname).with(any_args).and_return('1.gif')
794         Picture.any_instance.stub(:store_picture).with(@imager, '1.png').and_return(true)
795         Picture.any_instance.stub(:to_gif?).with(any_args).and_return(true)
796         Picture.any_instance.stub(:store_picture).with(@gifimager, '1.gif').and_return(false)
797         @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
798       end
799       it 'Falseを返す' do
800         r = @p.store(@imager)
801         r.should be_false
802       end
803     end
804   end
805   
806   describe '画像ファイルの作成に於いて' do
807     #PictureIo経由で画像を保存するための機能。ファイル名に自身のidを使うので事前に自身の保存が必要。
808     before do
809       @imager = ImagerTest.load "abc\ndef\nghi"
810       #原画ファイル削除だけは必ず成功するものとしておく
811       PictureIO::LocalPicture.any_instance.stub(:delete).with(any_args).and_return(true)
812       
813       Picture.any_instance.stub(:subdirs).with(any_args).and_return(['', 'v', 'h', 'vh'])
814       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
815     end
816     context '事前チェック' do
817       before do
818         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
819         PictureIO.picture_io.stub(:put).with(any_args).and_return(true)
820       end
821       it '画像ファイルの保存が4回呼ばれる' do
822         PictureIO.picture_io.should_receive(:put).with(any_args).exactly(4)
823         r = @p.store_picture(@imager, '1.png')
824       end
825       it '画像ファイルのベースへの保存が1回呼ばれる' do
826         PictureIO.picture_io.should_receive(:put).with("abc\ndef\nghi", '1.png', '').exactly(1)
827         r = @p.store_picture(@imager, '1.png')
828       end
829       it '画像ファイルの垂直反転への保存が1回呼ばれる' do
830         PictureIO.picture_io.should_receive(:put).with("cba\nfed\nihg", '1.png', 'v').exactly(1)
831         r = @p.store_picture(@imager, '1.png')
832       end
833       it '画像ファイルの水平反転への保存が1回呼ばれる' do
834         PictureIO.picture_io.should_receive(:put).with("ghi\ndef\nabc", '1.png', 'h').exactly(1)
835         r = @p.store_picture(@imager, '1.png')
836       end
837       it '画像ファイルの垂直水平反転への保存が1回呼ばれる' do
838         PictureIO.picture_io.should_receive(:put).with("ihg\nfed\ncba", '1.png', 'vh').exactly(1)
839         r = @p.store_picture(@imager, '1.png')
840       end
841     end
842     context 'つつがなく終わるとき' do
843       before do
844         #すべての処理を正常パターンで通過させ、保存機能をチェックする。
845         PictureIO.picture_io.stub(:put).with(any_args).and_return(true)
846       end
847       it 'Trueを返す' do
848         r = @p.store_picture(@imager, '1.png')
849         r.should be_true
850       end
851     end
852     context '例外ケース' do
853       before do
854         PictureIO.picture_io.stub(:put).with(any_args).and_return(false)
855       end
856       it 'Falseを返す' do
857         r = @p.store_picture(@imager, '1.png')
858         r.should be_false
859       end
860     end
861     
862   end
863   
864   describe '墨塗に於いて' do
865     before do
866       @p = FactoryGirl.create :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :ext => 'png'
867     end
868     context '事前チェック' do
869       before do
870         @imager = ImagerTest.load "abc\ndef\nghi"
871         Picture.any_instance.stub(:store).with(any_args).and_return(true)
872         PettanImager.stub(:load).with(any_args).and_return(@imager)
873       end
874       it '画像ライブラリにロードを依頼している' do
875         PettanImager.should_receive(:load).with(any_args).exactly(1)
876         r = @p.unpublish
877       end
878       it '自身に作成を依頼している' do
879         Picture.any_instance.should_receive(:store).with(any_args).exactly(1)
880         r = @p.unpublish
881       end
882     end
883     context 'つつがなく終わるとき' do
884       before do
885         Picture.any_instance.stub(:store).with(any_args).and_return(true)
886       end
887       it 'Trueを返す' do
888         r = @p.unpublish
889         r.should be_true
890       end
891     end
892     #例外ケース
893     context '画像ライブラリのロードに失敗したとき' do
894       before do
895         PettanImager.stub(:load).and_return(false)
896       end
897       it 'Falseを返す' do
898         r = @p.unpublish
899         r.should be_false
900       end
901     end
902     context '作成に失敗したとき' do
903       before do
904         Picture.any_instance.stub(:store).with(any_args).and_return(false)
905       end
906       it 'Falseを返す' do
907         r = @p.unpublish
908         r.should be_false
909       end
910     end
911   end
912   
913   describe 'フラグ展開に於いて' do
914     before do
915       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id,
916         :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}"
917     end
918     context 'json展開チェック' do
919       it '展開してなければ展開して@flagsに保管する' do
920         @p.flags.should_not be_nil
921       end
922       it '展開できなければ{}' do
923         @p.settings += '}'
924         @p.flags.is_a?(Hash).should be_true
925         @p.flags.empty?.should be_true
926       end
927     end
928     context 'openについて' do
929       it '@flag_openに保管する' do
930         @p.flag_open.should_not be_nil
931       end
932       it '本当にフラグHashからじゃなく、変数から取得してる?' do
933         @p.flag_open
934         @p.flags = nil
935         @p.flag_open.should_not be_nil
936       end
937       it '1を返す' do
938         @p.flag_open.should eq 1
939       end
940     end
941     context 'commercialについて' do
942       it '@flag_commercialに保管する' do
943         @p.flag_commercial.should_not be_nil
944       end
945       it '本当にフラグHashからじゃなく、変数から取得してる?' do
946         @p.flag_commercial
947         @p.flags = nil
948         @p.flag_commercial.should_not be_nil
949       end
950       it '2を返す' do
951         @p.flag_commercial.should eq 2
952       end
953     end
954     context 'officialについて' do
955       it '@flag_officialに保管する' do
956         @p.flag_official.should_not be_nil
957       end
958       it '本当にフラグHashからじゃなく、変数から取得してる?' do
959         @p.flag_official
960         @p.flags = nil
961         @p.flag_official.should_not be_nil
962       end
963       it 'を返す' do
964         @p.flag_official.should eq 3
965       end
966     end
967     context 'attributionについて' do
968       it '@flag_attributionに保管する' do
969         @p.flag_attribution.should_not be_nil
970       end
971       it '本当にフラグHashからじゃなく、変数から取得してる?' do
972         @p.flag_attribution
973         @p.flags = nil
974         @p.flag_attribution.should_not be_nil
975       end
976       it '4を返す' do
977         @p.flag_attribution.should eq 4
978       end
979     end
980     context 'deriveについて' do
981       it '@flag_deriveに保管する' do
982         @p.flag_derive.should_not be_nil
983       end
984       it '本当にフラグHashからじゃなく、変数から取得してる?' do
985         @p.flag_derive
986         @p.flags = nil
987         @p.flag_derive.should_not be_nil
988       end
989       it '5を返す' do
990         @p.flag_derive.should eq 5
991       end
992     end
993     context 'thumbnailについて' do
994       it '@flag_thumbnailに保管する' do
995         @p.flag_thumbnail.should_not be_nil
996       end
997       it '本当にフラグHashからじゃなく、変数から取得してる?' do
998         @p.flag_thumbnail
999         @p.flags = nil
1000         @p.flag_thumbnail.should_not be_nil
1001       end
1002       it '6を返す' do
1003         @p.flag_thumbnail.should eq 6
1004       end
1005     end
1006     context 'gif_convertについて' do
1007       it '@flag_gif_convertに保管する' do
1008         @p.flag_gif_convert.should_not be_nil
1009       end
1010       it '本当にフラグHashからじゃなく、変数から取得してる?' do
1011         @p.flag_gif_convert
1012         @p.flags = nil
1013         @p.flag_gif_convert.should_not be_nil
1014       end
1015       it '7を返す' do
1016         @p.flag_gif_convert.should eq 7
1017       end
1018     end
1019     context 'reverseについて' do
1020       it '@flag_reverseに保管する' do
1021         @p.flag_reverse.should_not be_nil
1022       end
1023       it '本当にフラグHashからじゃなく、変数から取得してる?' do
1024         @p.flag_reverse
1025         @p.flags = nil
1026         @p.flag_reverse.should_not be_nil
1027       end
1028       it '8を返す' do
1029         @p.flag_reverse.should eq 8
1030       end
1031     end
1032     context 'resizeについて' do
1033       it '@flag_resizeに保管する' do
1034         @p.flag_resize.should_not be_nil
1035       end
1036       it '本当にフラグHashからじゃなく、変数から取得してる?' do
1037         @p.flag_resize
1038         @p.flags = nil
1039         @p.flag_resize.should_not be_nil
1040       end
1041       it '9を返す' do
1042         @p.flag_resize.should eq 9
1043       end
1044     end
1045     context 'sync_vhについて' do
1046       it '@flag_sync_vhに保管する' do
1047         @p.flag_sync_vh.should_not be_nil
1048       end
1049       it '本当にフラグHashからじゃなく、変数から取得してる?' do
1050         @p.flag_sync_vh
1051         @p.flags = nil
1052         @p.flag_sync_vh.should_not be_nil
1053       end
1054       it '10を返す' do
1055         @p.flag_sync_vh.should eq 10
1056       end
1057     end
1058     context 'overlapについて' do
1059       it '@flag_overlapに保管する' do
1060         @p.flag_overlap.should_not be_nil
1061       end
1062       it '本当にフラグHashからじゃなく、変数から取得してる?' do
1063         @p.flag_overlap
1064         @p.flags = nil
1065         @p.flag_overlap.should_not be_nil
1066       end
1067       it '11を返す' do
1068         @p.flag_overlap.should eq 11
1069       end
1070     end
1071   end
1072
1073   describe 'クレジットデータに於いて' do
1074     before do
1075       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
1076       @p = FactoryGirl.build :picture, :original_picture_id => @op.id, :license_id => @license.id, :artist_id => @artist.id, :credit => '{"system_picture_id": 2}'
1077     end
1078     it 'system_picture_idが入っている' do
1079       res = @p.credit_data
1080       res["system_picture_id"].should eq 2
1081     end
1082   end
1083   
1084   describe 'エクスポートに於いて' do
1085     before do
1086       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
1087       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 0
1088       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
1089       @p2 = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 1, :updated_at => Time.now + 1000
1090       #開始日時以前の実素材
1091       @old_op = FactoryGirl.create :original_picture, :artist_id => @artist.id
1092       @old_p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @old_op.id, :license_id => @license.id, :revision => 0, :updated_at => Time.now - 1000
1093       @old_rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @old_op.id, :license_id => @license.id, :picture_id => @old_p.id
1094       #他人の実素材
1095       @other_op = FactoryGirl.create :original_picture, :artist_id => @other_artist.id
1096       @other_p = FactoryGirl.create :picture, :artist_id => @other_artist.id, :original_picture_id => @other_op.id, :license_id => @license.id, :revision => 0, :updated_at => Time.now + 100
1097       @other_rp = FactoryGirl.create :resource_picture, :artist_id => @other_artist.id, :original_picture_id => @other_op.id, :license_id => @license.id, :picture_id => @other_p.id
1098       #貸手からの実素材排除
1099       @outer_artist = FactoryGirl.create :artist_yas, :author_id => nil
1100       @outer_op = FactoryGirl.create :original_picture, :artist_id => @outer_artist.id
1101       @outer_p = FactoryGirl.create :picture, :artist_id => @outer_artist.id, :original_picture_id => @outer_op.id, :license_id => @license.id, :revision => 0
1102       @outer_rp = FactoryGirl.create :resource_picture, :artist_id => @outer_artist.id, :original_picture_id => @outer_op.id, :license_id => @license.id, :picture_id => @outer_p.id
1103     end
1104     context 'つつがなく終わるとき' do
1105       it '開始日時が省略された場合はすべての内実素材を返す' do
1106         r = Picture.export 
1107         r.should eq [@p2, @other_p, @p, @old_p]
1108       end
1109       it '開始日時以降に更新された内実素材を返す' do
1110         r = Picture.export @p.updated_at - 100
1111         r.should eq [@p2, @other_p, @p]
1112       end
1113     end
1114   end
1115   
1116   describe 'リストのjson化に於いて' do
1117     before do
1118       @op = FactoryGirl.create :original_picture, :artist_id => @artist.id
1119       @p = FactoryGirl.create :picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :revision => 0
1120       @rp = FactoryGirl.create :resource_picture, :artist_id => @artist.id, :original_picture_id => @op.id, :license_id => @license.id, :picture_id => @p.id
1121       @other_op = FactoryGirl.create :original_picture, :artist_id => @other_artist.id
1122       @other_p = FactoryGirl.create :picture, :artist_id => @other_artist.id, :original_picture_id => @other_op.id, :license_id => @license.id, :revision => 0, :updated_at => Time.now + 100
1123       @other_rp = FactoryGirl.create :resource_picture, :artist_id => @other_artist.id, :original_picture_id => @other_op.id, :license_id => @license.id, :picture_id => @other_p.id
1124       Picture.any_instance.stub(:restore).with(any_args).and_return('picture binary data')
1125     end
1126     context 'つつがなく終わるとき' do
1127       it 'json文字列を返す' do
1128         r = Picture.list_as_json_text Picture.all 
1129         lambda {
1130           j = JSON.parse r
1131         }.should_not raise_error(JSON::ParserError)
1132       end
1133       it '実素材リストを返す' do
1134         r = Picture.list_as_json_text Picture.all 
1135         j = JSON.parse r
1136         j.size.should eq 2
1137       end
1138       it '各実素材に画像データを添えて返す' do
1139         r = Picture.list_as_json_text Picture.all 
1140         j = JSON.parse r
1141         j.first['picture_data'].should_not be_nil
1142         j.last['picture_data'].should_not be_nil
1143       end
1144     end
1145   end
1146   
1147 end