OSDN Git Service

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